summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2018-10-16 00:57:24 +0200
committerJ08nY2018-10-16 00:57:24 +0200
commit40ec0fea381a6538f5498b9fb75706ef9fa79f59 (patch)
tree06081d0b40f7fb8cb25024cf34717f1ae1b1066d
parent7e9917742785a9fd532a52231e95ddad5775555f (diff)
downloadECTester-40ec0fea381a6538f5498b9fb75706ef9fa79f59.tar.gz
ECTester-40ec0fea381a6538f5498b9fb75706ef9fa79f59.tar.zst
ECTester-40ec0fea381a6538f5498b9fb75706ef9fa79f59.zip
-rw-r--r--.gitmodules3
-rw-r--r--README.md1
-rw-r--r--build-standalone.xml7
-rw-r--r--docs/LIBS.md12
m---------ext/boringssl0
-rw-r--r--src/cz/crcs/ectester/standalone/ECTesterStandalone.java2
-rw-r--r--src/cz/crcs/ectester/standalone/libs/BoringsslLib.java19
-rw-r--r--src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java82
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/Makefile11
-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/boringssl.c504
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/native.h181
17 files changed, 866 insertions, 37 deletions
diff --git a/.gitmodules b/.gitmodules
index 0fb6b09..bab94d9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "ext/mscng"]
path = ext/mscng
url = https://github.com/J08nY/mscng-dev-kit
+[submodule "ext/boringssl"]
+ path = ext/boringssl
+ url = https://boringssl.googlesource.com/boringssl
diff --git a/README.md b/README.md
index 5118c31..370f144 100644
--- a/README.md
+++ b/README.md
@@ -225,6 +225,7 @@ Currently supported libraries include:
- BouncyCastle
- SunEC
- OpenSSL
+ - BoringSSL
- Crypto++
- libtomcrypt
- botan
diff --git a/build-standalone.xml b/build-standalone.xml
index 685f791..c141509 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -157,6 +157,13 @@
<class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Mscng"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$Mscng"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$Mscng"/>
+ <class name="cz.crcs.ectester.standalone.libs.BoringsslLib"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeProvider$Boringssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$Boringssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPublicKey$Boringssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Boringssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$Boringssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$Boringssl"/>
</javah>
</target>
</project>
diff --git a/docs/LIBS.md b/docs/LIBS.md
index 00dcaaf..ad7aaf0 100644
--- a/docs/LIBS.md
+++ b/docs/LIBS.md
@@ -7,7 +7,6 @@ Popular libraries with at least some ECC support:
- [mbedTLS](https://tls.mbed.org/)
- [Nettle](http://www.lysator.liu.se/~nisse/nettle/)
- [OpenSSL (FIPS mode)](https://www.openssl.org/docs/fipsnotes.html)
- - [BoringSSL](https://boringssl.googlesource.com/boringssl)
- [Microsoft .NET crypto](https://docs.microsoft.com/en-us/dotnet/standard/security/cryptography-model)
# Supported libraries
@@ -61,6 +60,17 @@ Popular libraries with at least some ECC support:
- 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)
+ - [BoringSSL](https://boringssl.googlesource.com/boringssl)
+ - C
+ - Supports prime field curves only:
+ - Use Jacobian coordinates, and Montgomery ladder, also uses optimized arithmetic on NIST P-224, P-256.
+ - Bundled as a git submodule in `ext/boringssl`. To build and use run:
+```bash
+cd ext/boringssl
+mkdir build && cd build
+cmake -DBUILD_SHARED_LIBS=1 -GNinja ..
+ninja
+```
- [Botan](https://botan.randombit.net/)
- C++
- Uses blinded(randomized) Montgomery ladder.
diff --git a/ext/boringssl b/ext/boringssl
new file mode 160000
+Subproject 80aa6949756d327476750f9ea2c9700aa2a027c
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 1d7b821..cb6728b 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.3.0
*/
public class ECTesterStandalone {
- private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib(), new CryptoppLib(), new OpensslLib(), new MscngLib()};
+ private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib(), new CryptoppLib(), new OpensslLib(), new BoringsslLib(), new MscngLib()};
private Config cfg;
private Options opts = new Options();
diff --git a/src/cz/crcs/ectester/standalone/libs/BoringsslLib.java b/src/cz/crcs/ectester/standalone/libs/BoringsslLib.java
new file mode 100644
index 0000000..60ca5d9
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/BoringsslLib.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 BoringsslLib extends NativeECLibrary {
+ public BoringsslLib() {
+ super("boringssl_provider", "lib_boringssl.so");
+ }
+
+ @Override
+ native Provider createProvider();
+
+ @Override
+ public native Set<String> getCurves();
+}
diff --git a/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java b/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
index 6b98cc1..ff23fd9 100644
--- a/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
+++ b/src/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
@@ -47,39 +47,19 @@ public abstract class NativeECLibrary extends ProviderECLibrary {
appData = Paths.get(System.getProperty("user.home"), ".local", "share");
}
}
+ /* Resolve and create the ECTester directories in appData. */
Path libDir = appData.resolve("ECTesterStandalone");
File libDirFile = libDir.toFile();
+ Path libReqDir = libDir.resolve("lib");
+ File libReqDirFile = libReqDir.toFile();
Path libPath = libDir.resolve(resource + "." + suffix);
- File libFile = libPath.toFile();
- URL jarURL = NativeECLibrary.class.getResource(LIB_RESOURCE_DIR + resource + "." + suffix);
- if (jarURL == null) {
- return false;
- }
- URLConnection jarConnection = jarURL.openConnection();
-
- /* Only write the file if it does not exist,
- * or if the existing one is older than the
- * one in the JAR.
- */
- boolean write = false;
- if (libDirFile.isDirectory() && libFile.isFile()) {
- long jarModified = jarConnection.getLastModified();
-
- long libModified = Files.getLastModifiedTime(libPath).toMillis();
- if (jarModified > libModified) {
- write = true;
- }
- } else {
- libDir.toFile().mkdirs();
- libFile.createNewFile();
- write = true;
- }
+ /* Create directory for shims and for requirements. */
+ libDirFile.mkdirs();
+ libReqDirFile.mkdirs();
- if (write) {
- Files.copy(jarConnection.getInputStream(), libPath, StandardCopyOption.REPLACE_EXISTING);
- }
- jarConnection.getInputStream().close();
+ /* Write the shim. */
+ writeNewer(resource + "." + suffix, libPath);
/*
* Need to hack in /usr/local/lib to path.
@@ -98,12 +78,24 @@ public abstract class NativeECLibrary extends ProviderECLibrary {
}
}
- for (String requirement : requriements) {
- System.loadLibrary(requirement);
- }
-
- if (suffix.equals("so")) {
- System.setProperty("java.library.path", path);
+ /* Load the requirements, if they are bundled, write them in and load them. */
+ try {
+ for (String requirement : requriements) {
+ if (requirement.endsWith(suffix)) {
+ /* The requirement is bundled, write it */
+ Path reqPath = libReqDir.resolve(requirement);
+ writeNewer(requirement, reqPath);
+ System.load(reqPath.toString());
+ } else {
+ System.loadLibrary(requirement);
+ }
+ }
+ } catch (UnsatisfiedLinkError ule) {
+ return false;
+ } finally {
+ if (suffix.equals("so")) {
+ System.setProperty("java.library.path", path);
+ }
}
System.load(libPath.toString());
@@ -116,5 +108,27 @@ public abstract class NativeECLibrary extends ProviderECLibrary {
return false;
}
+ private boolean isNewer(URLConnection jarConn, Path realPath) throws IOException {
+ if (realPath.toFile().isFile()) {
+ long jarModified = jarConn.getLastModified();
+ long realModified = Files.getLastModifiedTime(realPath).toMillis();
+ return jarModified > realModified;
+ }
+ return true;
+ }
+
+ private boolean writeNewer(String resource, Path outPath) throws IOException {
+ URL reqURL = NativeECLibrary.class.getResource(LIB_RESOURCE_DIR + resource);
+ if (reqURL == null) {
+ return false;
+ }
+ URLConnection reqConn = reqURL.openConnection();
+ if (isNewer(reqConn, outPath)) {
+ Files.copy(reqConn.getInputStream(), outPath, StandardCopyOption.REPLACE_EXISTING);
+ }
+ reqConn.getInputStream().close();
+ return true;
+ }
+
abstract Provider createProvider();
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
index 006a3b1..189a6dd 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
@@ -54,7 +54,7 @@ else
CXXFLAGS+=-O2
endif
-all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so
+all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so boringssl_provider.so
# Common utils
c_utils.o: c_utils.c
@@ -72,6 +72,15 @@ openssl.o: openssl.c
$(CC) $(shell pkg-config --cflags openssl) $(CFLAGS) -c $<
+# BoringSSL shim
+boringssl_provider.so: boringssl.o c_utils.o
+ $(CC) $(LFLAGS) -o $@ $^ -L. ../../../../../../../ext/boringssl/build/crypto/libcrypto.so
+ cp ../../../../../../../ext/boringssl/build/crypto/libcrypto.so lib_boringssl.so
+
+boringssl.o: boringssl.c
+ $(CC) -I../../../../../../../ext/boringssl/include/ $(CFLAGS) -c $<
+
+
# Libtomcrypt shim
tomcrypt_provider.so: tomcrypt.o c_utils.o
$(CC) $(LFLAGS) -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 4cd4a9d..a74c155 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -85,6 +85,12 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
}
}
+ public static class Boringssl extends Raw {
+ public Boringssl(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 33dd3ef..7c17646 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -86,6 +86,12 @@ public abstract class NativeECPublicKey implements ECPublicKey {
}
}
+ public static class Boringssl extends ANSIX962 {
+ public Boringssl(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 fdbdccf..5fca448 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -234,6 +234,26 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
+ public abstract static class Boringssl extends SimpleKeyAgreementSpi {
+ private String type;
+
+ public Boringssl(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 BoringsslECDH extends Boringssl {
+ public BoringsslECDH() {
+ super("ECDH");
+ }
+ }
+
public abstract static class Mscng extends ExtendedKeyAgreementSpi {
private String type;
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
index aa83479..77f0d18 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
@@ -180,6 +180,24 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
}
+ public static class Boringssl extends NativeKeyPairGeneratorSpi {
+ public Boringssl() {
+ 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);
+ }
+
public static abstract class Mscng extends NativeKeyPairGeneratorSpi {
private String type;
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
index fef2930..1399500 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
@@ -64,6 +64,16 @@ public abstract class NativeProvider extends Provider {
native void setup();
}
+ public static class Boringssl extends NativeProvider {
+
+ public Boringssl(String name, double version, String info) {
+ super(name, version, info);
+ }
+
+ @Override
+ native void setup();
+ }
+
public static class Mscng extends NativeProvider {
public Mscng(String name, double version, String info) {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
index 602b1c4..3f99771 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
@@ -328,6 +328,27 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
+ public abstract static class Boringssl extends SimpleSignatureSpi {
+ private String type;
+
+ public Boringssl(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 BoringsslECDSAwithNONE extends Boringssl {
+
+ public BoringsslECDSAwithNONE() {
+ super("NONEwithECDSA");
+ }
+ }
+
public abstract static class Mscng extends ExtendedSignatureSpi {
private String type;
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/boringssl.c b/src/cz/crcs/ectester/standalone/libs/jni/boringssl.c
new file mode 100644
index 0000000..0353741
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/jni/boringssl.c
@@ -0,0 +1,504 @@
+#include "native.h"
+#include <string.h>
+#include <stdio.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"
+
+
+static jclass provider_class;
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BoringsslLib_createProvider(JNIEnv *env, jobject self) {
+ /* Create the custom provider. */
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Boringssl");
+ 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);
+ long ver_hi = (OPENSSL_VERSION_NUMBER & 0xff000000L) >> 28;
+ long ver_mid = (OPENSSL_VERSION_NUMBER & 0xff0000L) >> 20;
+ long ver_low = (OPENSSL_VERSION_NUMBER & 0xff00L) >> 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_00024Boringssl_setup(JNIEnv *env, jobject self) {
+ ERR_load_crypto_strings();
+ CRYPTO_library_init();
+
+ INIT_PROVIDER(env, provider_class);
+
+ ADD_KPG(env, self, "EC", "Boringssl");
+ ADD_KA(env, self, "ECDH", "BoringsslECDH");
+ ADD_SIG(env, self, "NONEwithECDSA", "BoringsslECDSAwithNONE");
+
+ init_classes(env, "Boringssl");
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BoringsslLib_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_00024Boringssl_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, 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(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_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;
+
+ 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_00024Boringssl_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) {
+ int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(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);
+ 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));
+ BIGNUM *h = BN_new();
+ EC_GROUP_get_cofactor(curve, h, NULL);
+ jint cofactor = BN_get_word(h);
+ BN_free(h);
+
+ jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "<init>", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
+ 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);
+ if (!EC_KEY_generate_key(key)) {
+ 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);
+ BN_bn2bin_padded(key_priv, key_bytes, EC_KEY_get0_private_key(key));
+ (*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, 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_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_00024Boringssl_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_00024Boringssl_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;
+ }
+}
+
+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, 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(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_00024Boringssl_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);
+ if (ECDH_compute_key(result_data, secret_len, EC_KEY_get0_public_key(pub), priv, NULL) <= 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_00024Boringssl_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_00024Boringssl_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?
+ ECDSA_SIG *signature = ECDSA_do_sign(data_data, data_size, priv);
+ (*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_00024Boringssl_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);
+ int result = ECDSA_do_verify(data_data, data_size, sig_obj, pub);
+ 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 e3bf3d8..eb64b53 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -905,3 +905,184 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_BoringsslLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_BoringsslLib
+#define _Included_cz_crcs_ectester_standalone_libs_BoringsslLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_BoringsslLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BoringsslLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_BoringsslLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BoringsslLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_serialVersionUID 1421746759512286392LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_serialVersionUID 4112578634029874840LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl_serialVersionUID -4298000515446427739LL
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Boringssl
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Boringssl_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl_DEFAULT_KEYSIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl_DEFAULT_KEYSIZE 256L
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl
+ * Method: keysizeSupported
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Boringssl_keysizeSupported
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl
+ * Method: paramsSupported
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Boringssl_paramsSupported
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Boringssl_generate__ILjava_security_SecureRandom_2
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Boringssl
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Boringssl_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_Boringssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Boringssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Boringssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Boringssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Boringssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Boringssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Boringssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Boringssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Boringssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Boringssl
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Boringssl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Boringssl
+ * 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_00024Boringssl_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_Boringssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Boringssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Boringssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Boringssl
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Boringssl_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Boringssl
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Boringssl_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif