From 713b14add9496ae5b3df5bb51b02d449f4ca0cef Mon Sep 17 00:00:00 2001
From: J08nY
Date: Tue, 24 Jul 2018 22:46:49 +0200
Subject: WIP: Microsoft CryptoAPI Next Generation support.
---
build-standalone.xml | 5 +
.../ectester/standalone/ECTesterStandalone.java | 2 +-
src/cz/crcs/ectester/standalone/libs/MscngLib.java | 20 ++
src/cz/crcs/ectester/standalone/libs/jni/Makefile | 5 +-
.../standalone/libs/jni/NativeECPrivateKey.java | 6 +
.../standalone/libs/jni/NativeECPublicKey.java | 7 +
.../libs/jni/NativeKeyPairGeneratorSpi.java | 40 ++-
.../standalone/libs/jni/NativeProvider.java | 10 +
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 324 +++++++++++++++++++++
src/cz/crcs/ectester/standalone/libs/jni/native.h | 125 ++++++++
10 files changed, 540 insertions(+), 4 deletions(-)
create mode 100644 src/cz/crcs/ectester/standalone/libs/MscngLib.java
create mode 100644 src/cz/crcs/ectester/standalone/libs/jni/mscng.c
diff --git a/build-standalone.xml b/build-standalone.xml
index 3783f59..1e6a3d5 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -129,6 +129,11 @@
+
+
+
+
+
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index c3d42dc..2897d20 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(), new OpensslLib()};
+ private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib(), new CryptoppLib(), new OpensslLib(), new MscngLib()};
private Config cfg;
private Options opts = new Options();
diff --git a/src/cz/crcs/ectester/standalone/libs/MscngLib.java b/src/cz/crcs/ectester/standalone/libs/MscngLib.java
new file mode 100644
index 0000000..527a65b
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/MscngLib.java
@@ -0,0 +1,20 @@
+package cz.crcs.ectester.standalone.libs;
+
+import java.security.Provider;
+import java.util.Set;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class MscngLib extends NativeECLibrary {
+
+ public MscngLib() {
+ super("mscng_provider", "bcrypt");
+ }
+
+ @Override
+ native Provider createProvider();
+
+ @Override
+ public native Set getCurves();
+}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
index 22e41cb..6fe6857 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
@@ -43,7 +43,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 openssl_provider.so
+all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so mscng_provider.dll
# Common utils
c_utils.o: c_utils.c
@@ -85,6 +85,9 @@ cryptopp.o: cryptopp.cpp
$(CXX) $(shell pkg-config --cflags libcrypto++) $(CXXFLAGS) -c $<
+mscng_provider.dll: mscng.c
+
+
clean:
rm -rf *.o
rm -rf *.so
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
index 39539df..277ffa7 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -77,4 +77,10 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
super(keyData, params);
}
}
+
+ public static class Mscng extends Raw {
+ public Mscng(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 1085083..18cc2cb 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -1,5 +1,6 @@
package cz.crcs.ectester.standalone.libs.jni;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.common.util.ECUtil;
import org.bouncycastle.util.Arrays;
@@ -79,4 +80,10 @@ public abstract class NativeECPublicKey implements ECPublicKey {
super(keyData, params);
}
}
+
+ public static class Mscng extends ANSIX962 {
+ public Mscng(byte[] x, byte[] y, ECParameterSpec params) {
+ super(ByteUtil.concatenate(new byte[]{0x04}, x, y), params);
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
index 6e441e5..f7e7653 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
@@ -27,7 +27,7 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
@Override
public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
if (!paramsSupported(params)) {
- throw new InvalidAlgorithmParameterException("not supported.");
+ throw new InvalidAlgorithmParameterException("Not supported.");
}
this.params = params;
this.random = random;
@@ -41,8 +41,9 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
return generate(keysize, random);
} else if (useParams) {
return generate(params, random);
+ } else {
+ throw new IllegalStateException("Uninitialized KeyPair.");
}
- return null;
}
abstract boolean keysizeSupported(int keysize);
@@ -173,4 +174,39 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
@Override
native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
}
+
+ public static abstract class Mscng extends NativeKeyPairGeneratorSpi {
+ private String type;
+
+ public Mscng(String type) {
+ this.type = type;
+ initialize(256, new SecureRandom());//TODO: maybe remove this default init?
+ }
+
+ @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 class MscngECDH extends Cryptopp {
+
+ public MscngECDH() {
+ super("ECDH");
+ }
+ }
+
+ public static class MscngECDSA extends Cryptopp {
+
+ public MscngECDSA() {
+ super("ECDSA");
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
index a4967e5..f580d74 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
@@ -59,4 +59,14 @@ public abstract class NativeProvider extends Provider {
@Override
native void setup();
}
+
+ public static class Mscng extends NativeProvider {
+
+ public Mscng(String name, double version, String info) {
+ super(name, version, info);
+ }
+
+ @Override
+ native void setup();
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
new file mode 100644
index 0000000..94a0f60
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -0,0 +1,324 @@
+#include "native.h"
+#include
+#include
+
+#include "c_utils.h"
+
+static jclass provider_class;
+
+#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
+#define NT_FAILURE(status) !NT_SUCCESS(status)
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self){
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
+ provider_class = (*env)->NewGlobalRef(env, local_provider_class);
+
+ jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V");
+
+ jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
+ double version = 1.0;
+ return (*env)->NewObject(env, provider_class, init, name, version, name);
+}
+
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup(JNIEnv *env, jobject self) {
+ INIT_PROVIDER(env, provider_class);
+
+ init_classes(env, "Mscng");
+}
+
+typedef struct {
+ const char *name;
+ ULONG bits;
+} named_curve_t;
+
+static named_curve_t named_curves[] = {
+ {"curve25519", 256},
+ {"brainpoolP160r1", 160},
+ {"brainpoolP160t1", 160},
+ {"brainpoolP192r1", 192},
+ {"brainpoolP192t1", 192},
+ {"brainpoolP224r1", 224},
+ {"brainpoolP224t1", 224},
+ {"brainpoolP256r1", 256},
+ {"brainpoolP256t1", 256},
+ {"brainpoolP320r1", 320},
+ {"brainpoolP320t1", 320},
+ {"brainpoolP384r1", 384},
+ {"brainpoolP384t1", 384},
+ {"brainpoolP512r1", 512},
+ {"brainpoolP512t1", 512},
+ {"ec192wapi", 192},
+ {"nistP192", 192},
+ {"nistP224", 224},
+ {"nistP256", 256},
+ {"nistP384", 384},
+ {"nistP521", 521},
+ {"numsP256t1", 256},
+ {"numsP384t1", 384},
+ {"numsP512t1", 512},
+ {"secP160k1", 160},
+ {"secP160r1", 160},
+ {"secP160r2", 160},
+ {"secP192k1", 192},
+ {"secP192r1", 192},
+ {"secP224k1", 224},
+ {"secP224r1", 224},
+ {"secP256k1", 256},
+ {"secP256r1", 256},
+ {"secP384r1", 384},
+ {"secP521r1", 521},
+ {"wtls12", 224},
+ {"wtls7", 160},
+ {"wtls9", 160},
+ {"x962P192v1", 192},
+ {"x962P192v2", 192},
+ {"x962P192v3", 192},
+ {"x962P239v1", 239},
+ {"x962P239v2", 239},
+ {"x962P239v3", 239},
+ {"x962P256v1", 256}
+};
+
+static const named_curve_t* lookup_curve(const char *name) {
+ for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
+ if (strcasecmp(name, named_curves[i].name) == 0) {
+ return &named_curves[i];
+ }
+ }
+ return NULL;
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_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, "", "()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);
+
+ for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
+ jstring curve_name = (*env)->NewStringUTF(env, named_curves[i].name);
+ (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name);
+ }
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
+ return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported(JNIEnv *env, jobject self, jobject params) {
+ if (params == NULL) {
+ return JNI_FALSE;
+ }
+
+ 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);
+ const named_curve_t *curve = lookup_curve(utf_name);
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return curve == NULL ? JNI_FALSE : JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
+ return NULL;
+}
+
+static jobject bytes_to_biginteger(JNIEnv *env, PBYTE bytes, int len) {
+ jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V");
+ jbyteArray bytes = (*env)->NewByteArray(env, len);
+ jbyte *data = (*env)->GetByteArrayElements(env, bytes, NULL);
+ memcpy(data, bytes, len);
+ (*env)->ReleaseByteArrayElements(env, bytes, data, 0);
+ jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, bytes);
+ return result;
+}
+
+static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, ULONG paramLength) {
+ // Taken from https://github.com/dotnet/corefx, thanks! This API is nowhere to be found.
+ //
+ // BCRYPT_ECC_PARAMETER_HEADER header
+ // byte[cbFieldLength] P
+ // byte[cbFieldLength] A
+ // byte[cbFieldLength] B
+ // byte[cbFieldLength] G.X
+ // byte[cbFieldLength] G.Y
+ // byte[cbSubgroupOrder] Order (n)
+ // byte[cbCofactor] Cofactor (h)
+ // byte[cbSeed] Seed
+
+ // BCRYPT_ECC_PARAMETER_HEADER
+ // internal int Version; //Version of the structure
+ // internal ECC_CURVE_TYPE_ENUM CurveType; //Supported curve types.
+ // internal ECC_CURVE_ALG_ID_ENUM CurveGenerationAlgId; //For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
+ // internal int cbFieldLength; //Byte length of the fields P, A, B, X, Y.
+ // internal int cbSubgroupOrder; //Byte length of the subgroup.
+ // internal int cbCofactor; //Byte length of cofactor of G in E.
+ // internal int cbSeed; //Byte length of the seed used to generate the curve.
+
+ // internal enum ECC_CURVE_TYPE_ENUM : int
+ // {
+ // BCRYPT_ECC_PRIME_SHORT_WEIERSTRASS_CURVE = 0x1,
+ // BCRYPT_ECC_PRIME_TWISTED_EDWARDS_CURVE = 0x2,
+ // BCRYPT_ECC_PRIME_MONTGOMERY_CURVE = 0x3,
+ // }
+
+ // internal enum ECC_CURVE_ALG_ID_ENUM : int
+ // {
+ // BCRYPT_NO_CURVE_GENERATION_ALG_ID = 0x0,
+ // }
+ BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)eccParams;
+ PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
+
+ //cbFieldLength
+ PBYTE P = paramsStart;
+ PBYTE A = p + header->cbFieldLength;
+ PBYTE B = A + header->cbFieldLength;
+ PBYTE GX = B + header->cbFieldLength;
+ PBYTE GY = GX + header->cbFieldLength;
+
+ //cbSubgroupOrder
+ PBYTE N = GY + header->cbFieldLength;
+
+ //cbCofactor
+ PBYTE H = N + header->cbSubgroupOrder;
+
+ //cbSeed
+ PBYTE S = H + header->cbCofactor;
+
+ jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
+
+ jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "", "(Ljava/math/BigInteger;)V");
+ jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
+
+ jobject a_int = bytes_to_biginteger(env, A, header->cbFieldLength);
+ jobject b_int = bytes_to_biginteger(env, B, header->cbFieldLength);
+
+ jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "", "(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);
+
+ jobject gx_int = bytes_to_biginteger(env, GX, header->cbFieldLength);
+ jobject gy_int = bytes_to_biginteger(env, GY, header->cbFieldLength);
+
+ jmethodID point_init = (*env)->GetMethodID(env, point_class, "", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
+
+ jobject n_int = bytes_to_biginteger(env, N, header->cbSubgroupOrder);
+
+ jobject h_int = bytes_to_biginteger(env, H, header->cbCofactor);
+ jmethodID bigint_to_int = (*env)->GetMethodID(env, biginteger_class, "intValue", "()I");
+ jint cof = (*env)->CallIntMethod(env, h_int, bigint_to_int);
+
+ jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
+ return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
+ BCRYPT_ALG_HANDLE kaHandle = NULL;
+ BCRYPT_KEY_HANDLE key = NULL;
+
+ //TODO: CUSTOM curve with BCRYPT_ECC_PARAMETERS??
+
+ jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR algo;
+ if (strcmp(type_data, "ECDH") == 0) {
+ algo = BCRYPT_ECDH_ALGORITHM;
+ } else if (strcmp(type_data, "ECDSA") == 0) {
+ algo = BCRYPT_ECDSA_ALGORITHM;
+ } else {
+ //err
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+
+ if (NT_FAILURE(BCryptOpenAlgorithmProvider(&kaHandle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ //err
+ }
+
+ 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);
+ const named_curve_t *curve = lookup_curve(utf_name);
+ if (NT_FAILURE(BCryptSetProperty(kaHandle, BCRYPT_ECC_CURVE_NAME, utf_name, strlen(utf_name), 0))) {
+ //err
+ }
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+
+ ULONG paramsSize;
+ if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, NULL, 0, ¶msSize, 0))) {
+ //err
+ }
+ if (paramsSize == 0) {
+ //TODO: what now?
+ }
+
+ BYTE params[paramsSize];
+ if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, params, paramsSize, ¶msSize, 0))) {
+ //err
+ }
+
+ jobject ec_param_spec = create_ec_param_spec(env, params, paramsSize);
+
+ if (NT_FAILURE(BCryptGenerateKeyPair(kaHandle, &key, curve.bits, 0)) {
+ //err
+ }
+
+ if (NT_FAILURE(BCryptFinalizeKeyPair(key, 0))) {
+ //err
+ }
+
+ ULONG bufSize;
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ //err
+ }
+
+ BYTE privBuf[bufSize];
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufsize, &bufSize, 0))) {
+ //err
+ }
+
+ // privBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // byte[cbKey] Q.X
+ // byte[cbKey] Q.Y
+ // byte[cbKey] D
+ BCRYPT_ECCKEY_BLOB *header = (BCRYPT_ECCKEY_BLOB*)privBuf;
+ PBYTE x = &privBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
+ PBYTE y = x + header->cbKey;
+ PBYTE priv = y + header->cbKey;
+
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, header->cbKey);
+ jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ memcpy(key_priv, priv, header->cbKey);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
+
+ jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([BLjava/security/spec/ECParameterSpec;)V");
+ jobject privkey = (*env)->NewObject(env, privkey_class, ec_priv_init, priv_bytes, ec_priv_param_spec);
+
+ jbyteArray x_bytes = (*env)->NewByteArray(env, header->cbKey);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, x, header->cbKey);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+ jbyteArray y_bytes = (*env)->NewByteArray(env, header->cbKey);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, y, header->cbKey);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+
+ jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[BLjava/security/spec/ECParameterSpec;)V");
+ jobject pubkey = (*env)->NewObject(env, pubkey_class, ec_pub_init, x_bytes, y_bytes, ec_pub_param_spec);
+
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+
+ BCryptDestroyKey(key);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+}
\ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index af68fd4..6e2b2bf 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -684,3 +684,128 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_MscngLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_MscngLib
+#define _Included_cz_crcs_ectester_standalone_libs_MscngLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_MscngLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_MscngLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 1421746759512286392LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 4112578634029874840LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -4298000515446427739LL
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: keysizeSupported
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: paramsSupported
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_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_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
--
cgit v1.3.1
From 7f7d6503589c50c2990556a550c7a5f252d7d789 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Wed, 25 Jul 2018 19:38:03 +0200
Subject: Add KeyAgreement support to Mscng.
---
build-standalone.xml | 1 +
.../standalone/libs/jni/NativeECPrivateKey.java | 45 ++-
.../standalone/libs/jni/NativeECPublicKey.java | 44 ++-
.../standalone/libs/jni/NativeKeyAgreementSpi.java | 49 ++-
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 333 ++++++++++++++++++---
src/cz/crcs/ectester/standalone/libs/jni/native.h | 19 ++
6 files changed, 424 insertions(+), 67 deletions(-)
diff --git a/build-standalone.xml b/build-standalone.xml
index 1e6a3d5..62b66de 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -134,6 +134,7 @@
+
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
index 277ffa7..7980773 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -1,5 +1,6 @@
package cz.crcs.ectester.standalone.libs.jni;
+import cz.crcs.ectester.common.util.ByteUtil;
import org.bouncycastle.util.Arrays;
import java.math.BigInteger;
@@ -12,10 +13,12 @@ import java.security.spec.ECParameterSpec;
public abstract class NativeECPrivateKey implements ECPrivateKey {
private String algorithm;
private String format;
+ ECParameterSpec params;
- public NativeECPrivateKey(String algorithm, String format) {
+ public NativeECPrivateKey(String algorithm, String format, ECParameterSpec params) {
this.algorithm = algorithm;
this.format = format;
+ this.params = params;
}
@Override
@@ -28,14 +31,19 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
return format;
}
+ @Override
+ public ECParameterSpec getParams() {
+ return params;
+ }
+
+ public abstract byte[] getData();
+
private static class Raw extends NativeECPrivateKey {
- private byte[] keyData;
- private ECParameterSpec params;
+ byte[] keyData;
public Raw(byte[] keyData, ECParameterSpec params) {
- super("EC", "raw");
+ super("EC", "raw", params);
this.keyData = keyData;
- this.params = params;
}
@Override
@@ -48,9 +56,8 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
return Arrays.clone(keyData);
}
- @Override
- public ECParameterSpec getParams() {
- return params;
+ public byte[] getData() {
+ return getEncoded();
}
}
@@ -79,8 +86,28 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
}
public static class Mscng extends Raw {
- public Mscng(byte[] keyData, ECParameterSpec params) {
+ private byte[] header;
+ private byte[] x;
+ private byte[] y;
+
+ public Mscng(byte[] header, byte[] x, byte[] y, byte[] keyData, ECParameterSpec params) {
super(keyData, params);
+ this.header = header;
+ this.x = x;
+ this.y = y;
+ }
+
+ public byte[] getHeader() {
+ return Arrays.clone(header);
+ }
+
+ public byte[] getBlob() {
+ return ByteUtil.concatenate(header, x, y, keyData);
+ }
+
+ @Override
+ public byte[] getData() {
+ return getBlob();
}
}
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
index 18cc2cb..e44ff49 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -15,10 +15,12 @@ import java.security.spec.ECPoint;
public abstract class NativeECPublicKey implements ECPublicKey {
private String algorithm;
private String format;
+ ECParameterSpec params;
- public NativeECPublicKey(String algorithm, String format) {
+ public NativeECPublicKey(String algorithm, String format, ECParameterSpec params) {
this.algorithm = algorithm;
this.format = format;
+ this.params = params;
}
@Override
@@ -31,14 +33,19 @@ public abstract class NativeECPublicKey implements ECPublicKey {
return format;
}
+ @Override
+ public ECParameterSpec getParams() {
+ return params;
+ }
+
+ public abstract byte[] getData();
+
private static class ANSIX962 extends NativeECPublicKey {
- private byte[] keyData;
- private ECParameterSpec params;
+ byte[] keyData;
public ANSIX962(byte[] keyData, ECParameterSpec params) {
- super("EC", "ANSI X9.62");
+ super("EC", "ANSI X9.62", params);
this.keyData = keyData;
- this.params = params;
}
@Override
@@ -51,9 +58,8 @@ public abstract class NativeECPublicKey implements ECPublicKey {
return Arrays.clone(keyData);
}
- @Override
- public ECParameterSpec getParams() {
- return params;
+ public byte[] getData() {
+ return ECUtil.toX962Uncompressed(getW(), params);
}
}
@@ -82,8 +88,28 @@ public abstract class NativeECPublicKey implements ECPublicKey {
}
public static class Mscng extends ANSIX962 {
- public Mscng(byte[] x, byte[] y, ECParameterSpec params) {
+ private byte[] header;
+ private byte[] x;
+ private byte[] y;
+
+ public Mscng(byte[] header, byte[] x, byte[] y, ECParameterSpec params) {
super(ByteUtil.concatenate(new byte[]{0x04}, x, y), params);
+ this.header = header;
+ this.x = x;
+ this.y = y;
+ }
+
+ public byte[] getHeader() {
+ return Arrays.clone(header);
+ }
+
+ public byte[] getBlob() {
+ return ByteUtil.concatenate(header, x, y);
+ }
+
+ @Override
+ public byte[] getData() {
+ return getBlob();
}
}
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index 47d1fcc..1211519 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -61,8 +61,18 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
- byte[] pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), params.getCurve());
- byte[] privkey = ECUtil.toByteArray(privateKey.getS(), params.getCurve().getField().getFieldSize());
+ byte[] pubkey;
+ if (publicKey instanceof NativeECPublicKey) {
+ pubkey = ((NativeECPublicKey) publicKey).getData();
+ } else {
+ pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), params.getCurve());
+ }
+ byte[] privkey;
+ if (privateKey instanceof NativeECPrivateKey) {
+ privkey = ((NativeECPrivateKey) privateKey).getData();
+ } else {
+ privkey = ECUtil.toByteArray(privateKey.getS(), params.getCurve().getField().getFieldSize());
+ }
return generateSecret(pubkey, privkey, params);
}
@@ -171,4 +181,39 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
super("ECDH");
}
}
+
+ public abstract static class Mscng extends NativeKeyAgreementSpi {
+ private String type;
+
+ public Mscng(String type) {
+ this.type = type;
+ }
+
+ @Override
+ native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+ }
+
+ public static class MscngECDHwithSHA1KDF extends Mscng {
+ public MscngECDHwithSHA1KDF() {
+ super("ECDHwithSHA1KDF");
+ }
+ }
+
+ public static class MscngECDHwithSHA256KDF extends Mscng {
+ public MscngECDHwithSHA256KDF() {
+ super("ECDHwithSHA256KDF");
+ }
+ }
+
+ public static class MscngECDHwithSHA384KDF extends Mscng {
+ public MscngECDHwithSHA384KDF() {
+ super("ECDHwithSHA384KDF");
+ }
+ }
+
+ public static class MscngECDHwithSHA512KDF extends Mscng {
+ public MscngECDHwithSHA512KDF() {
+ super("ECDHwithSHA512KDF");
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 94a0f60..aa986d1 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -23,6 +23,14 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createP
JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup(JNIEnv *env, jobject self) {
INIT_PROVIDER(env, provider_class);
+ ADD_KPG(env, self, "ECDH", "MscngECDH");
+ ADD_KPG(env, self, "ECDSA", "MscngECDSA");
+
+ ADD_KA(env, self, "ECDHwithSHA1KDF", "MscngECDHwithSHA1KDF");
+ ADD_KA(env, self, "ECDHwithSHA256KDF", "MscngECDHwithSHA256KDF");
+ ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
+ ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
+
init_classes(env, "Mscng");
}
@@ -119,6 +127,18 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
const named_curve_t *curve = lookup_curve(utf_name);
(*env)->ReleaseStringUTFChars(env, name, utf_name);
return curve == NULL ? JNI_FALSE : JNI_TRUE;
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject 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, curve, get_field);
+
+ if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
} else {
return JNI_FALSE;
}
@@ -139,6 +159,16 @@ static jobject bytes_to_biginteger(JNIEnv *env, PBYTE bytes, int len) {
return result;
}
+static void biginteger_to_bytes(JNIEnv *env, jobject bigint, PBYTE bytes, ULONG len) {
+ 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);
+ memcpy(bytes, &byte_data[byte_length - len], len);
+ (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
+}
+
static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, ULONG paramLength) {
// Taken from https://github.com/dotnet/corefx, thanks! This API is nowhere to be found.
//
@@ -218,12 +248,190 @@ static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, ULONG paramLen
return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
}
+static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
+ 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, "getB", "()Ljava/math/BigInteger;");
+ jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
+
+ jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
+
+ jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
+ jobject p = (*env)->CallObjectMethod(env, field, get_p);
+
+ 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);
+
+ jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
+ jobject gy = (*env)->CallObjectMethod(env, g, get_y);
+
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
+
+ jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
+ jint h = (*env)->CallIntMethod(env, params, get_h);
+
+ jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
+ jint order_bits = (*env)->CallIntMethod(env, n, get_bitlength);
+ jint order_bytes = (order_bits + 7) / 8;
+
+ // header_size + 5*bytes + order_bytes + cof_size + 0
+ ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5*bytes + order_bytes + sizeof(jint) + 0;
+ *curve = calloc(buSize, 1);
+ BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
+ header->Version = 1;
+ header->CurveType = 1; //1 -> Prime short Weierstrass, 2 -> Prime Twisted Edwards, 3 -> Montgomery
+ header->CurveGenerationAlgId = 0;
+ header->cbFieldLength = bytes;
+ header->cbSubgroupOrder = order_bytes;
+ header->cbCofactor = sizeof(jint);
+ header->cbSeed = 0;
+
+ PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
+
+ biginteger_to_bytes(env, p, paramsStart, bytes);
+ biginteger_to_bytes(env, a, paramsStart + bytes, bytes);
+ biginteger_to_bytes(env, b, paramsStart + 2*bytes, bytes);
+ biginteger_to_bytes(env, gx, paramsStart + 3*bytes, bytes);
+ biginteger_to_bytes(env, gy, paramsStart + 4*bytes, bytes);
+ biginteger_to_bytes(env, n, paramsStart + 5*bytes, order_bytes);
+ jint *cof_ptr = (jint *) (paramsStart + 5*bytes + order_bytes);
+ *cof_ptr = h;
+ return bufSize;
+}
+
+static bool init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
+ if (NT_FAILURE(BCryptOpenAlgorithmProvider(&handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ //err
+ return false;
+ }
+
+ 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);
+ const named_curve_t *curve = lookup_curve(utf_name);
+ if (NT_FAILURE(BCryptSetProperty(handle, BCRYPT_ECC_CURVE_NAME, utf_name, strlen(utf_name), 0))) {
+ //err
+ return false;
+ }
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ PBYTE curve;
+ ULONG curveLen = create_curve(env, params, &curve);
+ if (NT_FAILURE(BCryptSetProperty(handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
+ //err
+ return false;
+ }
+ free(curve);
+ }
+ return true;
+}
+
+static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
+ ULONG bufSize = 0;
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ //err
+ }
+ if (bufSize == 0) {
+ //err
+ }
+
+ BYTE privBuf[bufSize];
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufsize, &bufSize, 0))) {
+ //err
+ }
+
+ // privBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // byte[cbKey] Q.X
+ // byte[cbKey] Q.Y
+ // byte[cbKey] D
+ BCRYPT_ECCKEY_BLOB *privHeader = (BCRYPT_ECCKEY_BLOB*)privBuf;
+ PBYTE priv_x = &privBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
+ PBYTE priv_y = priv_x + privHeader->cbKey;
+ PBYTE priv = priv_y + privHeader->cbKey;
+
+ jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, privHeader, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+
+ jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, priv_x, privHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+
+ jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, priv_y, privHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ memcpy(key_priv, priv, header->cbKey);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
+
+ jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
+}
+
+static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
+ ULONG bufSize = 0;
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
+ //err
+ }
+
+ BYTE pubBuf[bufSize];
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, pubBuf, bufSize, &bufSize, 0))) {
+ //err
+ }
+
+ // pubBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // byte[cbKey] Q.X
+ // byte[cbKey] Q.Y
+ BCRYPT_ECCKEY_BLOB *pubHeader = (BCRYPT_ECCKEY_BLOB*)pubBuf;
+ PBYTE pub_x = &pubBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
+ PBYTE pub_y = pub_x + pubHeader->cbKey;
+
+ jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, pubHeader, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+
+ jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, pub_x, pubHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+
+ jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, pub_y, pubHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+
+ jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
+}
+
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
BCRYPT_ALG_HANDLE kaHandle = NULL;
BCRYPT_KEY_HANDLE key = NULL;
- //TODO: CUSTOM curve with BCRYPT_ECC_PARAMETERS??
-
jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
@@ -238,25 +446,16 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
}
(*env)->ReleaseStringUTFChars(env, type, type_data);
- if (NT_FAILURE(BCryptOpenAlgorithmProvider(&kaHandle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ if (!init_algo(env, &kaHandle, algo, params)) {
//err
}
- 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);
- const named_curve_t *curve = lookup_curve(utf_name);
- if (NT_FAILURE(BCryptSetProperty(kaHandle, BCRYPT_ECC_CURVE_NAME, utf_name, strlen(utf_name), 0))) {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, name, utf_name);
-
ULONG paramsSize;
if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, NULL, 0, ¶msSize, 0))) {
//err
}
if (paramsSize == 0) {
- //TODO: what now?
+ //err
}
BYTE params[paramsSize];
@@ -274,51 +473,91 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
//err
}
- ULONG bufSize;
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ jobject privkey = key_to_privkey(env, key, ec_param_spec);
+ jobject pubkey = key_to_pubkey(env, key, ec_param_spec);
+
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+
+ BCryptDestroyKey(key);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+ jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR kdf_algo;
+ if (strcmp(type_data, "ECDHwithSHA1KDF") == 0) {
+ kdf_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA256KDF") == 0) {
+ kdf_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA384KDF") == 0) {
+ kdf_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA512KDF") == 0) {
+ kdf_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
//err
}
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
- BYTE privBuf[bufSize];
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufsize, &bufSize, 0))) {
+ BCRYPT_ALG_HANDLE kaHandle = NULL;
+
+ if (!init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params)) {
//err
}
- // privBuf looks like:
- // BCRYPT_ECCKEY_BLOB header
- // byte[cbKey] Q.X
- // byte[cbKey] Q.Y
- // byte[cbKey] D
- BCRYPT_ECCKEY_BLOB *header = (BCRYPT_ECCKEY_BLOB*)privBuf;
- PBYTE x = &privBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
- PBYTE y = x + header->cbKey;
- PBYTE priv = y + header->cbKey;
+ BCRYPT_KEY_HANDLE pkey = NULL;
+ BCRYPT_KEY_HANDLE skey = NULL;
- jbyteArray priv_bytes = (*env)->NewByteArray(env, header->cbKey);
- jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
- memcpy(key_priv, priv, header->cbKey);
- (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
- jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
- jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([BLjava/security/spec/ECParameterSpec;)V");
- jobject privkey = (*env)->NewObject(env, privkey_class, ec_priv_init, priv_bytes, ec_priv_param_spec);
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ //err
+ }
- jbyteArray x_bytes = (*env)->NewByteArray(env, header->cbKey);
- jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, x, header->cbKey);
- (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
- jbyteArray y_bytes = (*env)->NewByteArray(env, header->cbKey);
- jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, y, header->cbKey);
- (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+ BCRYPT_SECRET_HANDLE ka = NULL;
- jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
- jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[BLjava/security/spec/ECParameterSpec;)V");
- jobject pubkey = (*env)->NewObject(env, pubkey_class, ec_pub_init, x_bytes, y_bytes, ec_pub_param_spec);
+ if (NT_FAILURE(BCryptSecretAgreement(skey, pkey, &ka, 0))) {
+ //err
+ }
- jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+ BCryptBufferDesc paramList = {0};
+ BCryptBuffer kdfParams[1] = {0};
+ kdfParams[0].BufferType = KDF_HASH_ALGORITHM;
+ kdfParams[0].cbBuffer = (DWORD)((wcslen(kdf_algo) + 1) * sizeof(WCHAR));
+ kdfParams[0].pvBuffer = (PVOID)kdf_algo;
+ paramList.cBuffers = 1;
+ paramList.pBuffers = kdfParams;
+ paramList.ulVersion = BCRYPTBUFFER_VERSION;
+
+ //TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
+ ULONG bufSize = 0;
+ if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, NULL, 0, &bufSize, 0))) {
+ //err
+ }
- BCryptDestroyKey(key);
+ BYTE derived[bufSize];
+ if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, derived, bufSize, &bufSize, 0))) {
+ //err
+ }
+
+ jbyteArray result = (*env)->NewByteArray(env, bufSize);
+ jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
+ memcpy(result_data, derived, bufSize);
+ (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
+
+ BCryptDestroyKey(pkey);
+ BCryptDestroyKey(skey);
+ BCryptDestroySecret(ka);
BCryptCloseAlgorithmProvider(kaHandle, 0);
- return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+ return result;
}
\ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index 6e2b2bf..a4b5915 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -809,3 +809,22 @@ extern "C" {
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--
cgit v1.3.1
From fb3daa0163127efa94c147618d40547f506398f1 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Wed, 25 Jul 2018 21:37:28 +0200
Subject: Add Signature support to Mscng.
---
build-standalone.xml | 1 +
.../standalone/libs/jni/NativeSignatureSpi.java | 58 +++++++-
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 152 +++++++++++++++++++++
src/cz/crcs/ectester/standalone/libs/jni/native.h | 27 ++++
4 files changed, 236 insertions(+), 2 deletions(-)
diff --git a/build-standalone.xml b/build-standalone.xml
index 62b66de..692b02b 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -135,6 +135,7 @@
+
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
index 86cc95b..e347120 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
@@ -52,12 +52,24 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
@Override
protected byte[] engineSign() throws SignatureException {
- return sign(buffer.toByteArray(), ECUtil.toByteArray(signKey.getS(), params.getCurve().getField().getFieldSize()), params);
+ byte[] privkey;
+ if (signKey instanceof NativeECPrivateKey) {
+ privkey = ((NativeECPrivateKey) signKey).getData();
+ } else {
+ privkey = ECUtil.toByteArray(signKey.getS(), params.getCurve().getField().getFieldSize());
+ }
+ return sign(buffer.toByteArray(), privkey, params);
}
@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- return verify(sigBytes, buffer.toByteArray(), ECUtil.toX962Uncompressed(verifyKey.getW(), params), params);
+ byte[] pubkey;
+ if (verifyKey instanceof NativeECPublicKey) {
+ pubkey = ((NativeECPublicKey) verifyKey).getData();
+ } else {
+ pubkey = ECUtil.toX962Uncompressed(verifyKey.getW(), params);
+ }
+ return verify(sigBytes, buffer.toByteArray(), pubkey, params);
}
@Override
@@ -294,4 +306,46 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
super("NONEwithECDSA");
}
}
+
+ public abstract static class Mscng extends NativeSignatureSpi {
+ private String type;
+
+ public Mscng(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 MscngECDSAwithSHA1 extends Mscng {
+
+ public MscngECDSAwithSHA1() {
+ super("SHA1withECDSA");
+ }
+ }
+
+ public static class MscngECDSAwithSHA256 extends Mscng {
+
+ public MscngECDSAwithSHA256() {
+ super("SHA256withECDSA");
+ }
+ }
+
+ public static class MscngECDSAwithSHA384 extends Mscng {
+
+ public MscngECDSAwithSHA384() {
+ super("SHA384withECDSA");
+ }
+ }
+
+ public static class MscngECDSAwithSHA512 extends Mscng {
+
+ public MscngECDSAwithSHA512() {
+ super("SHA512withECDSA");
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index aa986d1..5b35cae 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -31,6 +31,11 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_
ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
+ ADD_SIG(env, self, "SHA1withECDSA", "MscngECDSAwithSHA1");
+ ADD_SIG(env, self, "SHA256withECDSA", "MscngECDSAwithSHA256");
+ ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
+ ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
+
init_classes(env, "Mscng");
}
@@ -523,6 +528,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
//err
}
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
BCRYPT_SECRET_HANDLE ka = NULL;
@@ -560,4 +566,150 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
BCryptDestroySecret(ka);
BCryptCloseAlgorithmProvider(kaHandle, 0);
return result;
+}
+
+static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) {
+ jclass mscng_sig_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_sig_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR hash_algo;
+ if (strcmp(type_data, "SHA1withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "SHA256withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "SHA384withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "SHA512withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
+ //err
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+ return hash_algo;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
+
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
+
+ if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
+ //err
+ }
+
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
+
+ if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ //err
+ }
+
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ //err
+ }
+
+ BYTE hash[hash_len];
+
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+
+ BCRYPT_KEY_HANDLE skey = NULL;
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+
+ DWORD sig_len = 0;
+ if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
+ //err
+ }
+
+ jbyteArray sig = (*env)->NewByteArray(env, sig_len);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
+
+ BCryptDestroyKey(skey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+
+ return sig;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) {
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
+
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
+
+ if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
+ //err
+ }
+
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
+
+ if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ //err
+ }
+
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ //err
+ }
+
+ BYTE hash[hash_len];
+
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+
+ BYTE hash[hash_len];
+
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+
+ BCRYPT_KEY_HANDLE pkey = NULL;
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, pub_data, pub_length, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+
+ jint sig_len = (*env)->GetArrayLength(env, sig);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ NTSTATUS result = BCryptVerifySignature(pkey, NULL, hash, hash_len, sig_data, sig_len, 0);
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
+
+ BCryptDestroyKey(pkey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+
+ if (result == STATUS_SUCCESS) {
+ return JNI_TRUE;
+ } else if (result == STATUS_INVALID_SIGNATURE) {
+ return JNI_FALSE;
+ } else {
+ //err
+ return JNI_FALSE;
+ }
}
\ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index a4b5915..a2dedae 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -828,3 +828,30 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--
cgit v1.3.1
From 2143be748effab61c04d4e0a8f8ca0833e1430d9 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Wed, 25 Jul 2018 22:26:00 +0200
Subject: Add note about Microsoft CNG support to docs.
---
README.md | 1 +
docs/LIBS.md | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index daabdd9..7121027 100644
--- a/README.md
+++ b/README.md
@@ -225,6 +225,7 @@ Currently supported libraries include:
- Crypto++
- libtomcrypt
- botan
+ - Microsoft CNG
For more information on ECC libraries see [LIBS](docs/LIBS.md).
diff --git a/docs/LIBS.md b/docs/LIBS.md
index 59a183f..3d5e5e8 100644
--- a/docs/LIBS.md
+++ b/docs/LIBS.md
@@ -7,7 +7,6 @@ Popular libraries with at least some ECC support:
- [Nettle](http://www.lysator.liu.se/~nisse/nettle/)
- [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)
# Supported libraries
@@ -77,4 +76,7 @@ Popular libraries with at least some ECC support:
- For prime field curves:
- Uses projective coordinates and sliding window scalar multiplication algorithm.
- For binary field curves:
- - Uses affine coordinates and sliding window scalar multiplication algorithm.
\ No newline at end of file
+ - Uses affine coordinates and sliding window scalar multiplication algorithm.
+ - [Microsoft CNG](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx)
+ - C API.
+ - Closed source, uses whatever.
\ No newline at end of file
--
cgit v1.3.1
From ab7427c04fb0dc95906543dd9b4dc2c169215a98 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Thu, 26 Jul 2018 16:19:31 +0200
Subject: Add Microsoft CNG SDK as an external lib dependency.
---
.gitmodules | 3 +++
ext/mscng | 1 +
2 files changed, 4 insertions(+)
create mode 160000 ext/mscng
diff --git a/.gitmodules b/.gitmodules
index f832122..0fb6b09 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
[submodule "ext/libs"]
path = ext/libs
url = https://github.com/J08nY/javacard-libs
+[submodule "ext/mscng"]
+ path = ext/mscng
+ url = https://github.com/J08nY/mscng-dev-kit
diff --git a/ext/mscng b/ext/mscng
new file mode 160000
index 0000000..9f24ec3
--- /dev/null
+++ b/ext/mscng
@@ -0,0 +1 @@
+Subproject commit 9f24ec333ea0474633b3eb4752197b912aeca66e
--
cgit v1.3.1
From da8812b55dac70882f88870afe9877dd2927fa31 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Thu, 26 Jul 2018 19:59:33 +0200
Subject: Add Mscng build files to build on windows
---
build-standalone.xml | 13 ++
.../crcs/ectester/standalone/libs/jni/Makefile.bat | 136 +++++++++++++++++++++
2 files changed, 149 insertions(+)
create mode 100755 src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
diff --git a/build-standalone.xml b/build-standalone.xml
index 692b02b..fc135a0 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -84,11 +84,19 @@
+
+
+
+
+
+
+
+
@@ -97,6 +105,11 @@
osfamily="unix">
+
+
+
+
+
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
new file mode 100755
index 0000000..04b785e
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
@@ -0,0 +1,136 @@
+@if not defined _echo echo off
+setlocal EnableDelayedExpansion
+
+:: See if we are cleaning.
+if "%1" == "clean" (
+ echo ** cleaning
+ del mscng_provider.dll
+ exit
+)
+
+
+:: Determine arch.
+reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && (set ARCH=32& set ARCH_S=x86& set ARCH_VS=x86) || (set ARCH=64& set ARCH_S=x64& set ARCH_VS=amd64)
+
+echo ** ARCH %ARCH_S%
+
+
+:: Find a working visual studio environment.
+set found=0
+set vsw_path="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
+
+set vs_path=
+for /f "usebackq delims=" %%i in (`%vsw_path% -nologo -prerelease -latest -property installationPath`) do (
+ if exist "%%i\Common7\Tools\vsdevcmd.bat" (
+ echo ** VsDevCmd at %%i\Common7\Tools\vsdevcmd.bat
+ call "%%i\Common7\Tools\vsdevcmd.bat" -no_logo -arch=%ARCH_VS%
+ if ERRORLEVEL 1 (
+ echo nope.
+ ) else (
+ set found=1
+ set vs_path=%%i
+ break
+ )
+ )
+)
+
+:: Test if we have a visual studio env.
+if %found% EQU 0 (
+ echo Working VsDevCmd not found.
+ exit /b 2
+)
+
+echo ** VS_PATH %vs_path%
+
+
+:: Try to find vcruntime.
+set vc_base=%vs_path%\VC\Tools\MSVC\
+if exist %vc_base% (
+ set vc_version=
+ for /f "delims=" %%i in ('dir /b /on "!vc_base!"') do (
+ set vc_version=%%i
+ )
+ echo ** VC_VERSION !vc_version!
+ set vc_include=%vc_base%!vc_version!\include
+ set vc_lib=%vc_base%!vc_version!\lib\%ARCH_S%
+)
+
+
+:: Get the paths to Microsoft CNG SDK.
+set root_rel=..\..\..\..\..\..\..\
+set mscng_rel_include=ext\mscng\Include
+set mscng_rel_lib=ext\mscng\Lib
+
+pushd %root_rel%
+pushd %mscng_rel_include%
+set mscng_include=%CD%
+popd
+pushd %mscng_rel_lib%
+set mscng_lib=%CD%
+popd
+popd
+
+set mscng_lib_arch=%mscng_lib%\X%ARCH%
+
+echo ** CNG_INCLUDE !mscng_include!
+echo ** CNG_LIB !mscng_lib!
+
+
+:: Get the paths to Java JNI.
+if not defined JAVA_HOME (
+ set jva=
+ for /f "delims=" %%i in ('where javac') do (
+ set jva=%%~dpi
+ )
+ pushd !jva!\..
+ set JAVA_HOME=!CD!
+ popd
+)
+
+echo ** JAVA_HOME !JAVA_HOME!
+
+set JNI_INCLUDEDIR=%JAVA_HOME%\include
+set JNI_PLATFORMINCLUDEDIR=%JNI_INCLUDEDIR%\win32
+set JNI_LIBDIR=%JAVA_HOME%\lib
+
+
+:: Setup binaries.
+if not defined CC (
+ set CC=cl.exe
+)
+if not defined LINK (
+ set LINK=link.exe
+)
+
+echo ** CC !CC!
+echo ** LINK !LINK!
+
+
+:: Try to find uCRT.
+set ucrt_base=%ProgramFiles(x86)%\Windows Kits\10\
+if exist %ucrt_base% (
+ set ucrt_version=
+ for /f "delims=" %%i in ('dir /b /on "!ucrt_base!\Include"') do (
+ set ucrt_version=%%i
+ )
+ echo ** uCRT !ucrt_version!
+ set ucrt_include=%ucrt_base%Include\!ucrt_version!\ucrt
+ set ucrt_lib=%ucrt_base%Lib\!ucrt_version!
+ set ucrt_lib_arch=!ucrt_lib!\ucrt\%ARCH_S%
+)
+
+:: Setup INCLUDE paths.
+set INCLUDE_CLI=/I. /I"%JNI_INCLUDEDIR%" /I"%JNI_PLATFORMINCLUDEDIR%" /I"%mscng_include%"
+
+echo ** INCLUDE %INCLUDE%
+echo ** INCLUDE_CLI %INCLUDE_CLI%
+
+:: Setup LIB paths.
+set LIBPATH=/LIBPATH:"%JNI_LIBDIR%" /I"%mscng_lib_arch%"
+
+echo ** LIB %LIB%
+echo ** LIBPATH %LIBPATH%
+echo.
+
+
+%CC% /EHsc %INCLUDE_CLI% mscng.c /LD /Femscng_provider.dll
\ No newline at end of file
--
cgit v1.3.1
From 1a97e9c0070899bab201a2a14c9bb90ca1ca5e69 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Thu, 26 Jul 2018 23:06:40 +0200
Subject: Fix Mscng, finally!
---
.gitignore | 4 +
src/cz/crcs/ectester/standalone/libs/jni/Makefile | 24 +-
.../crcs/ectester/standalone/libs/jni/Makefile.bat | 10 +-
src/cz/crcs/ectester/standalone/libs/jni/c_utils.c | 4 +-
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 1458 ++++++++++----------
5 files changed, 769 insertions(+), 731 deletions(-)
diff --git a/.gitignore b/.gitignore
index af8dbf7..90700ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,4 +25,8 @@
# Built binaries in /src.
/src/**/*.a
/src/**/*.o
+/src/**/*.obj
/src/**/*.so
+/src/**/*.dll
+/src/**/*.exp
+/src/**/*.lib
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
index 6fe6857..006a3b1 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
@@ -38,12 +38,23 @@ CC?=gcc
CXX?=g++
STRIP?=strip
-LFLAGS+=-fPIC -g -shared
-CFLAGS+=-fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I.
-CXXFLAGS+=-fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I.
-
+LFLAGS+=-fPIC -shared
+CFLAGS+=-fPIC -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I.
+CXXFLAGS+=-fPIC -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I.
+
+DEBUG ?= 0
+
+ifeq ($(DEBUG), 1)
+ CFLAGS+=-g
+ LFLAGS+=-g
+ CXXFLAGS+=-g
+else
+ CFLAGS+=-O2
+ LFLAGS+=-O2
+ CXXFLAGS+=-O2
+endif
-all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so mscng_provider.dll
+all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so
# Common utils
c_utils.o: c_utils.c
@@ -85,9 +96,6 @@ cryptopp.o: cryptopp.cpp
$(CXX) $(shell pkg-config --cflags libcrypto++) $(CXXFLAGS) -c $<
-mscng_provider.dll: mscng.c
-
-
clean:
rm -rf *.o
rm -rf *.so
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
index 04b785e..a279750 100755
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
@@ -98,12 +98,8 @@ set JNI_LIBDIR=%JAVA_HOME%\lib
if not defined CC (
set CC=cl.exe
)
-if not defined LINK (
- set LINK=link.exe
-)
echo ** CC !CC!
-echo ** LINK !LINK!
:: Try to find uCRT.
@@ -120,17 +116,17 @@ if exist %ucrt_base% (
)
:: Setup INCLUDE paths.
-set INCLUDE_CLI=/I. /I"%JNI_INCLUDEDIR%" /I"%JNI_PLATFORMINCLUDEDIR%" /I"%mscng_include%"
+set INCLUDE_CLI=/I. /I"%JNI_INCLUDEDIR%" /I"%JNI_PLATFORMINCLUDEDIR%"
echo ** INCLUDE %INCLUDE%
echo ** INCLUDE_CLI %INCLUDE_CLI%
:: Setup LIB paths.
-set LIBPATH=/LIBPATH:"%JNI_LIBDIR%" /I"%mscng_lib_arch%"
+set LIBPATH=/LIBPATH:"%JNI_LIBDIR%"
echo ** LIB %LIB%
echo ** LIBPATH %LIBPATH%
echo.
-%CC% /EHsc %INCLUDE_CLI% mscng.c /LD /Femscng_provider.dll
\ No newline at end of file
+%CC% /EHsc %INCLUDE_CLI% mscng.c c_utils.c bcrypt.lib jvm.lib /Femscng_provider.dll /LD /link %LIBPATH%
\ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
index 336f4a1..9fee530 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
@@ -21,7 +21,7 @@ void init_classes(JNIEnv *env, const char* lib_name) {
ecgen_parameter_spec_class = (*env)->NewGlobalRef(env, local_ecgen_parameter_spec_class);
const char *pubkey_base = "cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey$";
- char pubkey_class_name[strlen(pubkey_base) + strlen(lib_name) + 1];
+ char pubkey_class_name[1024]; //strlen(pubkey_base) + strlen(lib_name) + 1
pubkey_class_name[0] = 0;
strcat(pubkey_class_name, pubkey_base);
strcat(pubkey_class_name, lib_name);
@@ -30,7 +30,7 @@ void init_classes(JNIEnv *env, const char* lib_name) {
pubkey_class = (*env)->NewGlobalRef(env, local_pubkey_class);
const char *privkey_base = "cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey$";
- char privkey_class_name[strlen(privkey_base) + strlen(lib_name) + 1];
+ char privkey_class_name[1024]; //strlen(privkey_base) + strlen(lib_name) + 1
privkey_class_name[0] = 0;
strcat(privkey_class_name, privkey_base);
strcat(privkey_class_name, lib_name);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 5b35cae..5dfee55 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -1,715 +1,745 @@
-#include "native.h"
-#include
-#include
-
-#include "c_utils.h"
-
-static jclass provider_class;
-
-#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
-#define NT_FAILURE(status) !NT_SUCCESS(status)
-
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self){
- jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
- provider_class = (*env)->NewGlobalRef(env, local_provider_class);
-
- jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V");
-
- jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
- double version = 1.0;
- return (*env)->NewObject(env, provider_class, init, name, version, name);
-}
-
-JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup(JNIEnv *env, jobject self) {
- INIT_PROVIDER(env, provider_class);
-
- ADD_KPG(env, self, "ECDH", "MscngECDH");
- ADD_KPG(env, self, "ECDSA", "MscngECDSA");
-
- ADD_KA(env, self, "ECDHwithSHA1KDF", "MscngECDHwithSHA1KDF");
- ADD_KA(env, self, "ECDHwithSHA256KDF", "MscngECDHwithSHA256KDF");
- ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
- ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
-
- ADD_SIG(env, self, "SHA1withECDSA", "MscngECDSAwithSHA1");
- ADD_SIG(env, self, "SHA256withECDSA", "MscngECDSAwithSHA256");
- ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
- ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
-
- init_classes(env, "Mscng");
-}
-
-typedef struct {
- const char *name;
- ULONG bits;
-} named_curve_t;
-
-static named_curve_t named_curves[] = {
- {"curve25519", 256},
- {"brainpoolP160r1", 160},
- {"brainpoolP160t1", 160},
- {"brainpoolP192r1", 192},
- {"brainpoolP192t1", 192},
- {"brainpoolP224r1", 224},
- {"brainpoolP224t1", 224},
- {"brainpoolP256r1", 256},
- {"brainpoolP256t1", 256},
- {"brainpoolP320r1", 320},
- {"brainpoolP320t1", 320},
- {"brainpoolP384r1", 384},
- {"brainpoolP384t1", 384},
- {"brainpoolP512r1", 512},
- {"brainpoolP512t1", 512},
- {"ec192wapi", 192},
- {"nistP192", 192},
- {"nistP224", 224},
- {"nistP256", 256},
- {"nistP384", 384},
- {"nistP521", 521},
- {"numsP256t1", 256},
- {"numsP384t1", 384},
- {"numsP512t1", 512},
- {"secP160k1", 160},
- {"secP160r1", 160},
- {"secP160r2", 160},
- {"secP192k1", 192},
- {"secP192r1", 192},
- {"secP224k1", 224},
- {"secP224r1", 224},
- {"secP256k1", 256},
- {"secP256r1", 256},
- {"secP384r1", 384},
- {"secP521r1", 521},
- {"wtls12", 224},
- {"wtls7", 160},
- {"wtls9", 160},
- {"x962P192v1", 192},
- {"x962P192v2", 192},
- {"x962P192v3", 192},
- {"x962P239v1", 239},
- {"x962P239v2", 239},
- {"x962P239v3", 239},
- {"x962P256v1", 256}
-};
-
-static const named_curve_t* lookup_curve(const char *name) {
- for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
- if (strcasecmp(name, named_curves[i].name) == 0) {
- return &named_curves[i];
- }
- }
- return NULL;
-}
-
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_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, "", "()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);
-
- for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
- jstring curve_name = (*env)->NewStringUTF(env, named_curves[i].name);
- (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name);
- }
- return result;
-}
-
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
- return JNI_FALSE;
-}
-
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported(JNIEnv *env, jobject self, jobject params) {
- if (params == NULL) {
- return JNI_FALSE;
- }
-
- 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);
- const named_curve_t *curve = lookup_curve(utf_name);
- (*env)->ReleaseStringUTFChars(env, name, utf_name);
- return curve == NULL ? JNI_FALSE : JNI_TRUE;
- } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
- jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
- jobject 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, curve, get_field);
-
- if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
- } else {
- return JNI_FALSE;
- }
-}
-
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
- throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
- return NULL;
-}
-
-static jobject bytes_to_biginteger(JNIEnv *env, PBYTE bytes, int len) {
- jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V");
- jbyteArray bytes = (*env)->NewByteArray(env, len);
- jbyte *data = (*env)->GetByteArrayElements(env, bytes, NULL);
- memcpy(data, bytes, len);
- (*env)->ReleaseByteArrayElements(env, bytes, data, 0);
- jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, bytes);
- return result;
-}
-
-static void biginteger_to_bytes(JNIEnv *env, jobject bigint, PBYTE bytes, ULONG len) {
- 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);
- memcpy(bytes, &byte_data[byte_length - len], len);
- (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
-}
-
-static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, ULONG paramLength) {
- // Taken from https://github.com/dotnet/corefx, thanks! This API is nowhere to be found.
- //
- // BCRYPT_ECC_PARAMETER_HEADER header
- // byte[cbFieldLength] P
- // byte[cbFieldLength] A
- // byte[cbFieldLength] B
- // byte[cbFieldLength] G.X
- // byte[cbFieldLength] G.Y
- // byte[cbSubgroupOrder] Order (n)
- // byte[cbCofactor] Cofactor (h)
- // byte[cbSeed] Seed
-
- // BCRYPT_ECC_PARAMETER_HEADER
- // internal int Version; //Version of the structure
- // internal ECC_CURVE_TYPE_ENUM CurveType; //Supported curve types.
- // internal ECC_CURVE_ALG_ID_ENUM CurveGenerationAlgId; //For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
- // internal int cbFieldLength; //Byte length of the fields P, A, B, X, Y.
- // internal int cbSubgroupOrder; //Byte length of the subgroup.
- // internal int cbCofactor; //Byte length of cofactor of G in E.
- // internal int cbSeed; //Byte length of the seed used to generate the curve.
-
- // internal enum ECC_CURVE_TYPE_ENUM : int
- // {
- // BCRYPT_ECC_PRIME_SHORT_WEIERSTRASS_CURVE = 0x1,
- // BCRYPT_ECC_PRIME_TWISTED_EDWARDS_CURVE = 0x2,
- // BCRYPT_ECC_PRIME_MONTGOMERY_CURVE = 0x3,
- // }
-
- // internal enum ECC_CURVE_ALG_ID_ENUM : int
- // {
- // BCRYPT_NO_CURVE_GENERATION_ALG_ID = 0x0,
- // }
- BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)eccParams;
- PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
-
- //cbFieldLength
- PBYTE P = paramsStart;
- PBYTE A = p + header->cbFieldLength;
- PBYTE B = A + header->cbFieldLength;
- PBYTE GX = B + header->cbFieldLength;
- PBYTE GY = GX + header->cbFieldLength;
-
- //cbSubgroupOrder
- PBYTE N = GY + header->cbFieldLength;
-
- //cbCofactor
- PBYTE H = N + header->cbSubgroupOrder;
-
- //cbSeed
- PBYTE S = H + header->cbCofactor;
-
- jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
-
- jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "", "(Ljava/math/BigInteger;)V");
- jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
-
- jobject a_int = bytes_to_biginteger(env, A, header->cbFieldLength);
- jobject b_int = bytes_to_biginteger(env, B, header->cbFieldLength);
-
- jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "", "(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);
-
- jobject gx_int = bytes_to_biginteger(env, GX, header->cbFieldLength);
- jobject gy_int = bytes_to_biginteger(env, GY, header->cbFieldLength);
-
- jmethodID point_init = (*env)->GetMethodID(env, point_class, "", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
- jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
-
- jobject n_int = bytes_to_biginteger(env, N, header->cbSubgroupOrder);
-
- jobject h_int = bytes_to_biginteger(env, H, header->cbCofactor);
- jmethodID bigint_to_int = (*env)->GetMethodID(env, biginteger_class, "intValue", "()I");
- jint cof = (*env)->CallIntMethod(env, h_int, bigint_to_int);
-
- jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
- return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
-}
-
-static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
- 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, "getB", "()Ljava/math/BigInteger;");
- jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
-
- jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
- jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
-
- jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
- jobject p = (*env)->CallObjectMethod(env, field, get_p);
-
- 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);
-
- jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
- jobject gy = (*env)->CallObjectMethod(env, g, get_y);
-
- jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
- jobject n = (*env)->CallObjectMethod(env, params, get_n);
-
- jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
- jint h = (*env)->CallIntMethod(env, params, get_h);
-
- jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
- jint order_bits = (*env)->CallIntMethod(env, n, get_bitlength);
- jint order_bytes = (order_bits + 7) / 8;
-
- // header_size + 5*bytes + order_bytes + cof_size + 0
- ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5*bytes + order_bytes + sizeof(jint) + 0;
- *curve = calloc(buSize, 1);
- BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
- header->Version = 1;
- header->CurveType = 1; //1 -> Prime short Weierstrass, 2 -> Prime Twisted Edwards, 3 -> Montgomery
- header->CurveGenerationAlgId = 0;
- header->cbFieldLength = bytes;
- header->cbSubgroupOrder = order_bytes;
- header->cbCofactor = sizeof(jint);
- header->cbSeed = 0;
-
- PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
-
- biginteger_to_bytes(env, p, paramsStart, bytes);
- biginteger_to_bytes(env, a, paramsStart + bytes, bytes);
- biginteger_to_bytes(env, b, paramsStart + 2*bytes, bytes);
- biginteger_to_bytes(env, gx, paramsStart + 3*bytes, bytes);
- biginteger_to_bytes(env, gy, paramsStart + 4*bytes, bytes);
- biginteger_to_bytes(env, n, paramsStart + 5*bytes, order_bytes);
- jint *cof_ptr = (jint *) (paramsStart + 5*bytes + order_bytes);
- *cof_ptr = h;
- return bufSize;
-}
-
-static bool init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
- if (NT_FAILURE(BCryptOpenAlgorithmProvider(&handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
- return false;
- }
-
- 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);
- const named_curve_t *curve = lookup_curve(utf_name);
- if (NT_FAILURE(BCryptSetProperty(handle, BCRYPT_ECC_CURVE_NAME, utf_name, strlen(utf_name), 0))) {
- //err
- return false;
- }
- (*env)->ReleaseStringUTFChars(env, name, utf_name);
- } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
- PBYTE curve;
- ULONG curveLen = create_curve(env, params, &curve);
- if (NT_FAILURE(BCryptSetProperty(handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
- //err
- return false;
- }
- free(curve);
- }
- return true;
-}
-
-static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
- ULONG bufSize = 0;
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
- //err
- }
- if (bufSize == 0) {
- //err
- }
-
- BYTE privBuf[bufSize];
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufsize, &bufSize, 0))) {
- //err
- }
-
- // privBuf looks like:
- // BCRYPT_ECCKEY_BLOB header
- // byte[cbKey] Q.X
- // byte[cbKey] Q.Y
- // byte[cbKey] D
- BCRYPT_ECCKEY_BLOB *privHeader = (BCRYPT_ECCKEY_BLOB*)privBuf;
- PBYTE priv_x = &privBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
- PBYTE priv_y = priv_x + privHeader->cbKey;
- PBYTE priv = priv_y + privHeader->cbKey;
-
- jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, privHeader, sizeof(BCRYPT_ECCKEY_BLOB));
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
-
- jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
- jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, priv_x, privHeader->cbKey);
- (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
-
- jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
- jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, priv_y, privHeader->cbKey);
- (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
-
- jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
- jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
- memcpy(key_priv, priv, header->cbKey);
- (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
-
- jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
- jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
-}
-
-static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
- ULONG bufSize = 0;
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
- //err
- }
-
- BYTE pubBuf[bufSize];
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, pubBuf, bufSize, &bufSize, 0))) {
- //err
- }
-
- // pubBuf looks like:
- // BCRYPT_ECCKEY_BLOB header
- // byte[cbKey] Q.X
- // byte[cbKey] Q.Y
- BCRYPT_ECCKEY_BLOB *pubHeader = (BCRYPT_ECCKEY_BLOB*)pubBuf;
- PBYTE pub_x = &pubBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
- PBYTE pub_y = pub_x + pubHeader->cbKey;
-
- jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, pubHeader, sizeof(BCRYPT_ECCKEY_BLOB));
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
-
- jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
- jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, pub_x, pubHeader->cbKey);
- (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
-
- jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
- jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, pub_y, pubHeader->cbKey);
- (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
-
- jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
- jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
-}
-
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
- BCRYPT_ALG_HANDLE kaHandle = NULL;
- BCRYPT_KEY_HANDLE key = NULL;
-
- jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR algo;
- if (strcmp(type_data, "ECDH") == 0) {
- algo = BCRYPT_ECDH_ALGORITHM;
- } else if (strcmp(type_data, "ECDSA") == 0) {
- algo = BCRYPT_ECDSA_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
-
- if (!init_algo(env, &kaHandle, algo, params)) {
- //err
- }
-
- ULONG paramsSize;
- if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, NULL, 0, ¶msSize, 0))) {
- //err
- }
- if (paramsSize == 0) {
- //err
- }
-
- BYTE params[paramsSize];
- if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, params, paramsSize, ¶msSize, 0))) {
- //err
- }
-
- jobject ec_param_spec = create_ec_param_spec(env, params, paramsSize);
-
- if (NT_FAILURE(BCryptGenerateKeyPair(kaHandle, &key, curve.bits, 0)) {
- //err
- }
-
- if (NT_FAILURE(BCryptFinalizeKeyPair(key, 0))) {
- //err
- }
-
- jobject privkey = key_to_privkey(env, key, ec_param_spec);
- jobject pubkey = key_to_pubkey(env, key, ec_param_spec);
-
- jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
-
- BCryptDestroyKey(key);
- BCryptCloseAlgorithmProvider(kaHandle, 0);
- return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
-}
-
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
- jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR kdf_algo;
- if (strcmp(type_data, "ECDHwithSHA1KDF") == 0) {
- kdf_algo = BCRYPT_SHA1_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA256KDF") == 0) {
- kdf_algo = BCRYPT_SHA256_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA384KDF") == 0) {
- kdf_algo = BCRYPT_SHA384_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA512KDF") == 0) {
- kdf_algo = BCRYPT_SHA512_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
-
- BCRYPT_ALG_HANDLE kaHandle = NULL;
-
- if (!init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params)) {
- //err
- }
-
- BCRYPT_KEY_HANDLE pkey = NULL;
- BCRYPT_KEY_HANDLE skey = NULL;
-
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
-
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
-
- BCRYPT_SECRET_HANDLE ka = NULL;
-
- if (NT_FAILURE(BCryptSecretAgreement(skey, pkey, &ka, 0))) {
- //err
- }
-
- BCryptBufferDesc paramList = {0};
- BCryptBuffer kdfParams[1] = {0};
- kdfParams[0].BufferType = KDF_HASH_ALGORITHM;
- kdfParams[0].cbBuffer = (DWORD)((wcslen(kdf_algo) + 1) * sizeof(WCHAR));
- kdfParams[0].pvBuffer = (PVOID)kdf_algo;
- paramList.cBuffers = 1;
- paramList.pBuffers = kdfParams;
- paramList.ulVersion = BCRYPTBUFFER_VERSION;
-
- //TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
- ULONG bufSize = 0;
- if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, NULL, 0, &bufSize, 0))) {
- //err
- }
-
- BYTE derived[bufSize];
- if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, derived, bufSize, &bufSize, 0))) {
- //err
- }
-
- jbyteArray result = (*env)->NewByteArray(env, bufSize);
- jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
- memcpy(result_data, derived, bufSize);
- (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
-
- BCryptDestroyKey(pkey);
- BCryptDestroyKey(skey);
- BCryptDestroySecret(ka);
- BCryptCloseAlgorithmProvider(kaHandle, 0);
- return result;
-}
-
-static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) {
- jclass mscng_sig_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_sig_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR hash_algo;
- if (strcmp(type_data, "SHA1withECDSA") == 0) {
- hash_algo = BCRYPT_SHA1_ALGORITHM;
- } else if (strcmp(type_data, "SHA256withECDSA") == 0) {
- hash_algo = BCRYPT_SHA256_ALGORITHM;
- } else if (strcmp(type_data, "SHA384withECDSA") == 0) {
- hash_algo = BCRYPT_SHA384_ALGORITHM;
- } else if (strcmp(type_data, "SHA512withECDSA") == 0) {
- hash_algo = BCRYPT_SHA512_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
- return hash_algo;
-}
-
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
- LPCWSTR hash_algo = get_sighash_algo(env, self);
-
- BCRYPT_ALG_HANDLE sigHandle = NULL;
-
- if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
- //err
- }
-
- BCRYPT_ALG_HANDLE hashHandle = NULL;
-
- if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- //err
- }
-
- DWORD dummy = 0;
- DWORD hash_len = 0;
- if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- //err
- }
-
- BYTE hash[hash_len];
-
- jint data_len = (*env)->GetArrayLength(env, data);
- jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
-
- BCRYPT_KEY_HANDLE skey = NULL;
-
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
-
- DWORD sig_len = 0;
- if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
- //err
- }
-
- jbyteArray sig = (*env)->NewByteArray(env, sig_len);
- jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
- if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
-
- BCryptDestroyKey(skey);
- BCryptCloseAlgorithmProvider(hashHandle, 0);
- BCryptCloseAlgorithmProvider(sigHandle, 0);
-
- return sig;
-}
-
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) {
- LPCWSTR hash_algo = get_sighash_algo(env, self);
-
- BCRYPT_ALG_HANDLE sigHandle = NULL;
-
- if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
- //err
- }
-
- BCRYPT_ALG_HANDLE hashHandle = NULL;
-
- if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- //err
- }
-
- DWORD dummy = 0;
- DWORD hash_len = 0;
- if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- //err
- }
-
- BYTE hash[hash_len];
-
- jint data_len = (*env)->GetArrayLength(env, data);
- jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
-
- BYTE hash[hash_len];
-
- jint data_len = (*env)->GetArrayLength(env, data);
- jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
-
- BCRYPT_KEY_HANDLE pkey = NULL;
-
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, pub_data, pub_length, 0))) {
- //err
- }
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
-
- jint sig_len = (*env)->GetArrayLength(env, sig);
- jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
- NTSTATUS result = BCryptVerifySignature(pkey, NULL, hash, hash_len, sig_data, sig_len, 0);
- (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
-
- BCryptDestroyKey(pkey);
- BCryptCloseAlgorithmProvider(hashHandle, 0);
- BCryptCloseAlgorithmProvider(sigHandle, 0);
-
- if (result == STATUS_SUCCESS) {
- return JNI_TRUE;
- } else if (result == STATUS_INVALID_SIGNATURE) {
- return JNI_FALSE;
- } else {
- //err
- return JNI_FALSE;
- }
+#include "native.h"
+#include
+#include
+
+#include "c_utils.h"
+
+static jclass provider_class;
+
+#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
+#define NT_FAILURE(status) !NT_SUCCESS(status)
+
+#define STATUS_SUCCESS 0x00000000
+#define STATUS_INVALID_SIGNATURE 0xC000A000
+
+typedef struct {
+ ULONG dwVersion; //Version of the structure
+ ECC_CURVE_TYPE_ENUM dwCurveType; //Supported curve types.
+ ECC_CURVE_ALG_ID_ENUM dwCurveGenerationAlgId; //For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
+ ULONG cbFieldLength; //Byte length of the fields P, A, B, X, Y.
+ ULONG cbSubgroupOrder; //Byte length of the subgroup.
+ ULONG cbCofactor; //Byte length of cofactor of G in E.
+ ULONG cbSeed; //Byte length of the seed used to generate the curve.
+} BCRYPT_ECC_PARAMETER_HEADER;
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self){
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
+ provider_class = (*env)->NewGlobalRef(env, local_provider_class);
+
+ jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V");
+
+ jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
+ double version = 1.0;
+ return (*env)->NewObject(env, provider_class, init, name, version, name);
+}
+
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup(JNIEnv *env, jobject self) {
+ INIT_PROVIDER(env, provider_class);
+
+ ADD_KPG(env, self, "ECDH", "MscngECDH");
+ ADD_KPG(env, self, "ECDSA", "MscngECDSA");
+
+ ADD_KA(env, self, "ECDHwithSHA1KDF", "MscngECDHwithSHA1KDF");
+ ADD_KA(env, self, "ECDHwithSHA256KDF", "MscngECDHwithSHA256KDF");
+ ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
+ ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
+
+ ADD_SIG(env, self, "SHA1withECDSA", "MscngECDSAwithSHA1");
+ ADD_SIG(env, self, "SHA256withECDSA", "MscngECDSAwithSHA256");
+ ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
+ ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
+
+ init_classes(env, "Mscng");
+}
+
+typedef struct {
+ const char *name;
+ ULONG bits;
+} named_curve_t;
+
+static named_curve_t named_curves[] = {
+ {"curve25519", 256},
+ {"brainpoolP160r1", 160},
+ {"brainpoolP160t1", 160},
+ {"brainpoolP192r1", 192},
+ {"brainpoolP192t1", 192},
+ {"brainpoolP224r1", 224},
+ {"brainpoolP224t1", 224},
+ {"brainpoolP256r1", 256},
+ {"brainpoolP256t1", 256},
+ {"brainpoolP320r1", 320},
+ {"brainpoolP320t1", 320},
+ {"brainpoolP384r1", 384},
+ {"brainpoolP384t1", 384},
+ {"brainpoolP512r1", 512},
+ {"brainpoolP512t1", 512},
+ {"ec192wapi", 192},
+ {"nistP192", 192},
+ {"nistP224", 224},
+ {"nistP256", 256},
+ {"nistP384", 384},
+ {"nistP521", 521},
+ {"numsP256t1", 256},
+ {"numsP384t1", 384},
+ {"numsP512t1", 512},
+ {"secP160k1", 160},
+ {"secP160r1", 160},
+ {"secP160r2", 160},
+ {"secP192k1", 192},
+ {"secP192r1", 192},
+ {"secP224k1", 224},
+ {"secP224r1", 224},
+ {"secP256k1", 256},
+ {"secP256r1", 256},
+ {"secP384r1", 384},
+ {"secP521r1", 521},
+ {"wtls12", 224},
+ {"wtls7", 160},
+ {"wtls9", 160},
+ {"x962P192v1", 192},
+ {"x962P192v2", 192},
+ {"x962P192v3", 192},
+ {"x962P239v1", 239},
+ {"x962P239v2", 239},
+ {"x962P239v3", 239},
+ {"x962P256v1", 256}
+};
+
+static const named_curve_t* lookup_curve(const char *name) {
+ for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
+ if (strcmp(name, named_curves[i].name) == 0) {
+ return &named_curves[i];
+ }
+ }
+ return NULL;
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_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, "", "()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);
+
+ for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
+ jstring curve_name = (*env)->NewStringUTF(env, named_curves[i].name);
+ (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name);
+ }
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
+ return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported(JNIEnv *env, jobject self, jobject params) {
+ if (params == NULL) {
+ return JNI_FALSE;
+ }
+
+ 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);
+ const named_curve_t *curve = lookup_curve(utf_name);
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return curve == NULL ? JNI_FALSE : JNI_TRUE;
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject 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, curve, get_field);
+
+ if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
+ return NULL;
+}
+
+static jobject bytes_to_biginteger(JNIEnv *env, PBYTE bytes, int len) {
+ jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V");
+ jbyteArray byte_array = (*env)->NewByteArray(env, len);
+ jbyte *data = (*env)->GetByteArrayElements(env, byte_array, NULL);
+ memcpy(data, bytes, len);
+ (*env)->ReleaseByteArrayElements(env, byte_array, data, 0);
+ jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, byte_array);
+ return result;
+}
+
+static void biginteger_to_bytes(JNIEnv *env, jobject bigint, PBYTE bytes, ULONG len) {
+ 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);
+ memcpy(bytes, &byte_data[byte_length - len], len);
+ (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
+}
+
+static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, ULONG paramLength) {
+ // Taken from https://github.com/dotnet/corefx, thanks! This API is nowhere to be found.
+ //
+ // BCRYPT_ECC_PARAMETER_HEADER header
+ // byte[cbFieldLength] P
+ // byte[cbFieldLength] A
+ // byte[cbFieldLength] B
+ // byte[cbFieldLength] G.X
+ // byte[cbFieldLength] G.Y
+ // byte[cbSubgroupOrder] Order (n)
+ // byte[cbCofactor] Cofactor (h)
+ // byte[cbSeed] Seed
+
+ // BCRYPT_ECC_PARAMETER_HEADER
+ // internal int Version; //Version of the structure
+ // internal ECC_CURVE_TYPE_ENUM CurveType; //Supported curve types.
+ // internal ECC_CURVE_ALG_ID_ENUM CurveGenerationAlgId; //For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
+ // internal int cbFieldLength; //Byte length of the fields P, A, B, X, Y.
+ // internal int cbSubgroupOrder; //Byte length of the subgroup.
+ // internal int cbCofactor; //Byte length of cofactor of G in E.
+ // internal int cbSeed; //Byte length of the seed used to generate the curve.
+
+ // internal enum ECC_CURVE_TYPE_ENUM : int
+ // {
+ // BCRYPT_ECC_PRIME_SHORT_WEIERSTRASS_CURVE = 0x1,
+ // BCRYPT_ECC_PRIME_TWISTED_EDWARDS_CURVE = 0x2,
+ // BCRYPT_ECC_PRIME_MONTGOMERY_CURVE = 0x3,
+ // }
+
+ // internal enum ECC_CURVE_ALG_ID_ENUM : int
+ // {
+ // BCRYPT_NO_CURVE_GENERATION_ALG_ID = 0x0,
+ // }
+ BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)eccParams;
+ PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
+
+ //cbFieldLength
+ PBYTE P = paramsStart;
+ PBYTE A = P + header->cbFieldLength;
+ PBYTE B = A + header->cbFieldLength;
+ PBYTE GX = B + header->cbFieldLength;
+ PBYTE GY = GX + header->cbFieldLength;
+
+ //cbSubgroupOrder
+ PBYTE N = GY + header->cbFieldLength;
+
+ //cbCofactor
+ PBYTE H = N + header->cbSubgroupOrder;
+
+ //cbSeed
+ PBYTE S = H + header->cbCofactor;
+
+ jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
+
+ jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "", "(Ljava/math/BigInteger;)V");
+ jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
+
+ jobject a_int = bytes_to_biginteger(env, A, header->cbFieldLength);
+ jobject b_int = bytes_to_biginteger(env, B, header->cbFieldLength);
+
+ jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "", "(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);
+
+ jobject gx_int = bytes_to_biginteger(env, GX, header->cbFieldLength);
+ jobject gy_int = bytes_to_biginteger(env, GY, header->cbFieldLength);
+
+ jmethodID point_init = (*env)->GetMethodID(env, point_class, "", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
+
+ jobject n_int = bytes_to_biginteger(env, N, header->cbSubgroupOrder);
+
+ jobject h_int = bytes_to_biginteger(env, H, header->cbCofactor);
+ jmethodID bigint_to_int = (*env)->GetMethodID(env, biginteger_class, "intValue", "()I");
+ jint cof = (*env)->CallIntMethod(env, h_int, bigint_to_int);
+
+ jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
+ return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
+}
+
+static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
+ 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, "getB", "()Ljava/math/BigInteger;");
+ jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
+
+ jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
+
+ jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
+ jobject p = (*env)->CallObjectMethod(env, field, get_p);
+
+ 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);
+
+ jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
+ jobject gy = (*env)->CallObjectMethod(env, g, get_y);
+
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
+
+ jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
+ jint h = (*env)->CallIntMethod(env, params, get_h);
+
+ jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
+ jint order_bits = (*env)->CallIntMethod(env, n, get_bitlength);
+ jint order_bytes = (order_bits + 7) / 8;
+
+ // header_size + 5*bytes + order_bytes + cof_size + 0
+ ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5*bytes + order_bytes + sizeof(jint) + 0;
+ *curve = calloc(bufSize, 1);
+ BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
+ header->dwVersion = 1;
+ header->dwCurveType = 1; //1 -> Prime short Weierstrass, 2 -> Prime Twisted Edwards, 3 -> Montgomery
+ header->dwCurveGenerationAlgId = 0;
+ header->cbFieldLength = bytes;
+ header->cbSubgroupOrder = order_bytes;
+ header->cbCofactor = sizeof(jint);
+ header->cbSeed = 0;
+
+ PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
+
+ biginteger_to_bytes(env, p, paramsStart, bytes);
+ biginteger_to_bytes(env, a, paramsStart + bytes, bytes);
+ biginteger_to_bytes(env, b, paramsStart + 2*bytes, bytes);
+ biginteger_to_bytes(env, gx, paramsStart + 3*bytes, bytes);
+ biginteger_to_bytes(env, gy, paramsStart + 4*bytes, bytes);
+ biginteger_to_bytes(env, n, paramsStart + 5*bytes, order_bytes);
+ jint *cof_ptr = (jint *) (paramsStart + 5*bytes + order_bytes);
+ *cof_ptr = h;
+ return bufSize;
+}
+
+static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
+ if (NT_FAILURE(BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ //err
+ return 0;
+ }
+ ULONG result = 0;
+ 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);
+ jint utf_length = (*env)->GetStringUTFLength(env, name);
+ PUCHAR chars = calloc(utf_length + 1, 1);
+ (*env)->GetStringUTFRegion(env, name, 0, utf_length, chars);
+ const named_curve_t *curve = lookup_curve(chars);
+ if (NT_FAILURE(BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, chars, strlen(chars), 0))) {
+ //err
+ return 0;
+ }
+ free(chars);
+ result = curve->bits;
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ PBYTE curve;
+ ULONG curveLen = create_curve(env, params, &curve);
+ if (NT_FAILURE(BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
+ //err
+ return 0;
+ }
+ free(curve);
+
+ 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);
+ result = (bits + 7) / 8;
+ }
+ return result;
+}
+
+static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
+ ULONG bufSize = 0;
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ //err
+ }
+ if (bufSize == 0) {
+ //err
+ }
+
+ PBYTE privBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufSize, &bufSize, 0))) {
+ //err
+ }
+
+ // privBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // byte[cbKey] Q.X
+ // byte[cbKey] Q.Y
+ // byte[cbKey] D
+ BCRYPT_ECCKEY_BLOB *privHeader = (BCRYPT_ECCKEY_BLOB*)privBuf;
+ PBYTE priv_x = &privBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
+ PBYTE priv_y = priv_x + privHeader->cbKey;
+ PBYTE priv = priv_y + privHeader->cbKey;
+
+ jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, privHeader, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+
+ jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, priv_x, privHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+
+ jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, priv_y, privHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ memcpy(key_priv, priv, privHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
+
+ free(privBuf);
+
+ jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
+}
+
+static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
+ ULONG bufSize = 0;
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
+ //err
+ }
+
+ PBYTE pubBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, pubBuf, bufSize, &bufSize, 0))) {
+ //err
+ }
+
+ // pubBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // byte[cbKey] Q.X
+ // byte[cbKey] Q.Y
+ BCRYPT_ECCKEY_BLOB *pubHeader = (BCRYPT_ECCKEY_BLOB*)pubBuf;
+ PBYTE pub_x = &pubBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
+ PBYTE pub_y = pub_x + pubHeader->cbKey;
+
+ jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, pubHeader, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+
+ jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, pub_x, pubHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+
+ jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, pub_y, pubHeader->cbKey);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+
+ free(pubBuf);
+
+ jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
+ BCRYPT_ALG_HANDLE kaHandle = NULL;
+ BCRYPT_KEY_HANDLE key = NULL;
+
+ jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR algo;
+ if (strcmp(type_data, "ECDH") == 0) {
+ algo = BCRYPT_ECDH_ALGORITHM;
+ } else if (strcmp(type_data, "ECDSA") == 0) {
+ algo = BCRYPT_ECDSA_ALGORITHM;
+ } else {
+ //err
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+
+ ULONG bits = init_algo(env, &kaHandle, algo, params);
+ if (bits == 0) {
+ //err
+ }
+
+ ULONG paramsSize;
+ if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, NULL, 0, ¶msSize, 0))) {
+ //err
+ }
+ if (paramsSize == 0) {
+ //err
+ }
+
+ PBYTE eccParams = calloc(paramsSize, 1);
+ if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, eccParams, paramsSize, ¶msSize, 0))) {
+ //err
+ }
+
+ jobject ec_param_spec = create_ec_param_spec(env, eccParams, paramsSize);
+
+ free(eccParams);
+
+ if (NT_FAILURE(BCryptGenerateKeyPair(kaHandle, &key, bits, 0))) {
+ //err
+ }
+
+ if (NT_FAILURE(BCryptFinalizeKeyPair(key, 0))) {
+ //err
+ }
+
+ jobject privkey = key_to_privkey(env, key, ec_param_spec);
+ jobject pubkey = key_to_pubkey(env, key, ec_param_spec);
+
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+
+ BCryptDestroyKey(key);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+ jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR kdf_algo;
+ if (strcmp(type_data, "ECDHwithSHA1KDF") == 0) {
+ kdf_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA256KDF") == 0) {
+ kdf_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA384KDF") == 0) {
+ kdf_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA512KDF") == 0) {
+ kdf_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
+ //err
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+
+ BCRYPT_ALG_HANDLE kaHandle = NULL;
+
+ if (!init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params)) {
+ //err
+ }
+
+ BCRYPT_KEY_HANDLE pkey = NULL;
+ BCRYPT_KEY_HANDLE skey = NULL;
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+
+ BCRYPT_SECRET_HANDLE ka = NULL;
+
+ if (NT_FAILURE(BCryptSecretAgreement(skey, pkey, &ka, 0))) {
+ //err
+ }
+
+ BCryptBufferDesc paramList = {0};
+ BCryptBuffer kdfParams[1] = {0};
+ kdfParams[0].BufferType = KDF_HASH_ALGORITHM;
+ kdfParams[0].cbBuffer = (DWORD)((wcslen(kdf_algo) + 1) * sizeof(WCHAR));
+ kdfParams[0].pvBuffer = (PVOID)kdf_algo;
+ paramList.cBuffers = 1;
+ paramList.pBuffers = kdfParams;
+ paramList.ulVersion = BCRYPTBUFFER_VERSION;
+
+ //TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
+ ULONG bufSize = 0;
+ if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, NULL, 0, &bufSize, 0))) {
+ //err
+ }
+
+ PBYTE derived = calloc(bufSize, 1);
+ if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, derived, bufSize, &bufSize, 0))) {
+ //err
+ }
+
+ jbyteArray result = (*env)->NewByteArray(env, bufSize);
+ jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
+ memcpy(result_data, derived, bufSize);
+ (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
+
+ free(derived);
+
+ BCryptDestroyKey(pkey);
+ BCryptDestroyKey(skey);
+ BCryptDestroySecret(ka);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ return result;
+}
+
+static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) {
+ jclass mscng_sig_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_sig_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR hash_algo;
+ if (strcmp(type_data, "SHA1withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "SHA256withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "SHA384withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "SHA512withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
+ //err
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+ return hash_algo;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
+
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
+
+ if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
+ //err
+ }
+
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
+
+ if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ //err
+ }
+
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ //err
+ }
+
+ PBYTE hash = calloc(hash_len, 1);
+
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+
+ BCRYPT_KEY_HANDLE skey = NULL;
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+
+ DWORD sig_len = 0;
+ if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
+ //err
+ }
+
+ jbyteArray sig = (*env)->NewByteArray(env, sig_len);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
+
+ free(hash);
+
+ BCryptDestroyKey(skey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+
+ return sig;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) {
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
+
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
+
+ if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
+ //err
+ }
+
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
+
+ if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ //err
+ }
+
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ //err
+ }
+
+ PBYTE hash = calloc(hash_len, 1);
+
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+
+ BCRYPT_KEY_HANDLE pkey = NULL;
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &pkey, pub_data, pub_length, 0))) {
+ //err
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+
+ jint sig_len = (*env)->GetArrayLength(env, sig);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ NTSTATUS result = BCryptVerifySignature(pkey, NULL, hash, hash_len, sig_data, sig_len, 0);
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
+
+ free(hash);
+
+ BCryptDestroyKey(pkey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+
+ if (result == STATUS_SUCCESS) {
+ return JNI_TRUE;
+ } else if (result == STATUS_INVALID_SIGNATURE) {
+ return JNI_FALSE;
+ } else {
+ //err
+ return JNI_FALSE;
+ }
}
\ No newline at end of file
--
cgit v1.3.1
From eef13a358a3e45b3abbb2a11016cd1243b0b2b6a Mon Sep 17 00:00:00 2001
From: J08nY
Date: Fri, 27 Jul 2018 00:13:56 +0200
Subject: WIP: Fix mscng according to new API.
---
.../libs/jni/NativeKeyPairGeneratorSpi.java | 6 +-
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 84 +++++++++++++++++-----
2 files changed, 68 insertions(+), 22 deletions(-)
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
index f7e7653..7ca013a 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
@@ -180,7 +180,7 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
public Mscng(String type) {
this.type = type;
- initialize(256, new SecureRandom());//TODO: maybe remove this default init?
+ initialize(256, new SecureRandom());
}
@Override
@@ -196,14 +196,14 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
}
- public static class MscngECDH extends Cryptopp {
+ public static class MscngECDH extends Mscng {
public MscngECDH() {
super("ECDH");
}
}
- public static class MscngECDSA extends Cryptopp {
+ public static class MscngECDSA extends Mscng {
public MscngECDSA() {
super("ECDSA");
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 5dfee55..56502da 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -4,13 +4,15 @@
#include "c_utils.h"
+#include
+
static jclass provider_class;
#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
#define NT_FAILURE(status) !NT_SUCCESS(status)
-#define STATUS_SUCCESS 0x00000000
-#define STATUS_INVALID_SIGNATURE 0xC000A000
+#define STATUS_SUCCESS 0x00000000
+#define STATUS_INVALID_SIGNATURE 0xC000A000
typedef struct {
ULONG dwVersion; //Version of the structure
@@ -30,6 +32,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createP
jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
double version = 1.0;
+
+ printf("createProvider\n");
return (*env)->NewObject(env, provider_class, init, name, version, name);
}
@@ -49,6 +53,7 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_
ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
+ printf("setup\n");
init_classes(env, "Mscng");
}
@@ -106,7 +111,7 @@ static named_curve_t named_curves[] = {
};
static const named_curve_t* lookup_curve(const char *name) {
- for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
+ for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
if (strcmp(name, named_curves[i].name) == 0) {
return &named_curves[i];
}
@@ -114,6 +119,18 @@ static const named_curve_t* lookup_curve(const char *name) {
return NULL;
}
+static const named_curve_t* lookup_curve_bits(jint bitsize) {
+ printf("looking up %i\n", bitsize);
+ for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
+ printf("trying (%s, %i)\n", named_curves[i].name, named_curves[i].bits);
+ if (bitsize == named_curves[i].bits) {
+ printf("got it!\n");
+ return &named_curves[i];
+ }
+ }
+ return NULL;
+}
+
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurves(JNIEnv *env, jobject self) {
jclass hash_set_class = (*env)->FindClass(env, "java/util/TreeSet");
@@ -126,15 +143,19 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurv
jstring curve_name = (*env)->NewStringUTF(env, named_curves[i].name);
(*env)->CallBooleanMethod(env, result, hash_set_add, curve_name);
}
+ printf("getCurves\n");
return result;
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
- return JNI_FALSE;
+ printf("keysizeSupported\n");
+ return (lookup_curve_bits(keysize) == NULL) ? JNI_FALSE : JNI_TRUE;
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported(JNIEnv *env, jobject self, jobject params) {
- if (params == NULL) {
+ printf("paramsSupported\n");
+ if (params == NULL) {
+ printf("theyNull\n");
return JNI_FALSE;
}
@@ -162,11 +183,6 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
}
}
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
- throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
- return NULL;
-}
-
static jobject bytes_to_biginteger(JNIEnv *env, PBYTE bytes, int len) {
jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V");
jbyteArray byte_array = (*env)->NewByteArray(env, len);
@@ -463,10 +479,17 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_para
return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
}
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
+ return NULL;
+}
+
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
BCRYPT_ALG_HANDLE kaHandle = NULL;
BCRYPT_KEY_HANDLE key = NULL;
-
+
+ fprintf(stderr, "1\n");
+ fflush(stderr);
jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
@@ -477,47 +500,70 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
} else if (strcmp(type_data, "ECDSA") == 0) {
algo = BCRYPT_ECDSA_ALGORITHM;
} else {
- //err
+ fprintf(stderr, "err\n");
+ fflush(stderr);
}
(*env)->ReleaseStringUTFChars(env, type, type_data);
+ fprintf(stderr, "2\n");
+ fflush(stderr);
ULONG bits = init_algo(env, &kaHandle, algo, params);
if (bits == 0) {
- //err
+ fprintf(stderr, "err0\n");
+ fflush(stderr);
}
+ fprintf(stderr, "3\n");
+ fflush(stderr);
ULONG paramsSize;
if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, NULL, 0, ¶msSize, 0))) {
- //err
+ fprintf(stderr, "err\n");
+ fflush(stderr);
}
if (paramsSize == 0) {
- //err
+ fprintf(stderr, "err0\n");
+ fflush(stderr);
}
+ fprintf(stderr, "4\n");
+ fflush(stderr);
PBYTE eccParams = calloc(paramsSize, 1);
if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, eccParams, paramsSize, ¶msSize, 0))) {
- //err
+ fprintf(stderr, "err\n");
+ fflush(stderr);
}
- jobject ec_param_spec = create_ec_param_spec(env, eccParams, paramsSize);
+ jobject ec_param_spec = create_ec_param_spec(env, eccParams, paramsSize);
free(eccParams);
+ fprintf(stderr, "5\n");
+ fflush(stderr);
if (NT_FAILURE(BCryptGenerateKeyPair(kaHandle, &key, bits, 0))) {
- //err
+ fprintf(stderr, "err\n");
+ fflush(stderr);
}
+ fprintf(stderr, "6\n");
+ fflush(stderr);
if (NT_FAILURE(BCryptFinalizeKeyPair(key, 0))) {
- //err
+ fprintf(stderr, "err\n");
+ fflush(stderr);
}
jobject privkey = key_to_privkey(env, key, ec_param_spec);
jobject pubkey = key_to_pubkey(env, key, ec_param_spec);
+ fprintf(stderr, "7\n");
+ fflush(stderr);
jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+ fprintf(stderr, "8\n");
+ fflush(stderr);
BCryptDestroyKey(key);
BCryptCloseAlgorithmProvider(kaHandle, 0);
+ fprintf(stderr, "9\n");
+ fflush(stderr);
return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
--
cgit v1.3.1
From e109037811a9c17ecc296e2eb8e7a86957458943 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Fri, 27 Jul 2018 11:29:12 +0200
Subject: Bump Mscng sdk submodule.
---
ext/mscng | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ext/mscng b/ext/mscng
index 9f24ec3..084ce21 160000
--- a/ext/mscng
+++ b/ext/mscng
@@ -1 +1 @@
-Subproject commit 9f24ec333ea0474633b3eb4752197b912aeca66e
+Subproject commit 084ce2130403188ffd01aa04e44fea87b03236d4
--
cgit v1.3.1
From 0d961f0c0bdc5a0ace91bc7b2289055b26d4fbe7 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Fri, 27 Jul 2018 21:02:27 +0200
Subject: WIP: Mscng keygen works.
---
.gitignore | 1 +
docs/LIBS.md | 9 +-
.../crcs/ectester/standalone/libs/jni/Makefile.bat | 19 +-
.../standalone/libs/jni/NativeECPrivateKey.java | 10 +-
.../standalone/libs/jni/NativeECPublicKey.java | 10 +-
src/cz/crcs/ectester/standalone/libs/jni/c_utils.c | 4 +-
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 478 +++++++++++++--------
7 files changed, 346 insertions(+), 185 deletions(-)
diff --git a/.gitignore b/.gitignore
index 90700ba..f40221d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
# Built artifacts in /dist and /applet.
+/build/
/dist/lib/
/dist/ECTesterReader.jar
/dist/ECTesterReader-dist.jar
diff --git a/docs/LIBS.md b/docs/LIBS.md
index 3d5e5e8..d1a68d0 100644
--- a/docs/LIBS.md
+++ b/docs/LIBS.md
@@ -79,4 +79,11 @@ Popular libraries with at least some ECC support:
- Uses affine coordinates and sliding window scalar multiplication algorithm.
- [Microsoft CNG](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx)
- C API.
- - Closed source, uses whatever.
\ No newline at end of file
+ - Closed source.
+ - For prime field curves(only supports):
+ - Uses Short Weierstrass model.
+ - Uses Twisted Edwards model.
+ - Uses Montgomery model.
+ - Uses fixed window scalar multiplication.
+ - Uses Wnaf multi-scalar multiplication with interleaving.
+ - Uses Montgomery ladder.
\ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
index a279750..e337e70 100755
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
@@ -1,6 +1,11 @@
@if not defined _echo echo off
setlocal EnableDelayedExpansion
+:: ENV variables respected:
+:: - JAVA_HOME
+:: - CC
+:: - USE_EXT_MSCNG
+
:: See if we are cleaning.
if "%1" == "clean" (
echo ** cleaning
@@ -58,8 +63,8 @@ if exist %vc_base% (
:: Get the paths to Microsoft CNG SDK.
set root_rel=..\..\..\..\..\..\..\
-set mscng_rel_include=ext\mscng\Include
-set mscng_rel_lib=ext\mscng\Lib
+set mscng_rel_include=ext\mscng\10\Include
+set mscng_rel_lib=ext\mscng\10\Lib
pushd %root_rel%
pushd %mscng_rel_include%
@@ -115,15 +120,25 @@ if exist %ucrt_base% (
set ucrt_lib_arch=!ucrt_lib!\ucrt\%ARCH_S%
)
+
:: Setup INCLUDE paths.
set INCLUDE_CLI=/I. /I"%JNI_INCLUDEDIR%" /I"%JNI_PLATFORMINCLUDEDIR%"
+if defined USE_EXT_MSCNG (
+ set INCLUDE_CLI=!INCLUDE_CLI! /I"%mscng_include%"
+)
+
echo ** INCLUDE %INCLUDE%
echo ** INCLUDE_CLI %INCLUDE_CLI%
+
:: Setup LIB paths.
set LIBPATH=/LIBPATH:"%JNI_LIBDIR%"
+if defined USE_EXT_MSCNG (
+ set LIBPATH=!LIBPATH! /LIBPATH:"%mscng_lib_arch%"
+)
+
echo ** LIB %LIB%
echo ** LIBPATH %LIBPATH%
echo.
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
index 7980773..76786fe 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -43,7 +43,7 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
public Raw(byte[] keyData, ECParameterSpec params) {
super("EC", "raw", params);
- this.keyData = keyData;
+ this.keyData = Arrays.clone(keyData);
}
@Override
@@ -92,9 +92,9 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
public Mscng(byte[] header, byte[] x, byte[] y, byte[] keyData, ECParameterSpec params) {
super(keyData, params);
- this.header = header;
- this.x = x;
- this.y = y;
+ this.header = Arrays.clone(header);
+ this.x = Arrays.clone(x);
+ this.y = Arrays.clone(y);
}
public byte[] getHeader() {
@@ -102,7 +102,7 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
}
public byte[] getBlob() {
- return ByteUtil.concatenate(header, x, y, keyData);
+ return ByteUtil.concatenate(header, x, y, keyData);
}
@Override
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
index e44ff49..e55ed33 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -45,7 +45,7 @@ public abstract class NativeECPublicKey implements ECPublicKey {
public ANSIX962(byte[] keyData, ECParameterSpec params) {
super("EC", "ANSI X9.62", params);
- this.keyData = keyData;
+ this.keyData = Arrays.clone(keyData);
}
@Override
@@ -94,9 +94,9 @@ public abstract class NativeECPublicKey implements ECPublicKey {
public Mscng(byte[] header, byte[] x, byte[] y, ECParameterSpec params) {
super(ByteUtil.concatenate(new byte[]{0x04}, x, y), params);
- this.header = header;
- this.x = x;
- this.y = y;
+ this.header = Arrays.clone(header);
+ this.x = Arrays.clone(x);
+ this.y = Arrays.clone(y);
}
public byte[] getHeader() {
@@ -104,7 +104,7 @@ public abstract class NativeECPublicKey implements ECPublicKey {
}
public byte[] getBlob() {
- return ByteUtil.concatenate(header, x, y);
+ return ByteUtil.concatenate(header, x, y);
}
@Override
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
index 9fee530..f920fc4 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
@@ -21,7 +21,7 @@ void init_classes(JNIEnv *env, const char* lib_name) {
ecgen_parameter_spec_class = (*env)->NewGlobalRef(env, local_ecgen_parameter_spec_class);
const char *pubkey_base = "cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey$";
- char pubkey_class_name[1024]; //strlen(pubkey_base) + strlen(lib_name) + 1
+ char pubkey_class_name[2048] = { 0 }; //strlen(pubkey_base) + strlen(lib_name) + 1
pubkey_class_name[0] = 0;
strcat(pubkey_class_name, pubkey_base);
strcat(pubkey_class_name, lib_name);
@@ -30,7 +30,7 @@ void init_classes(JNIEnv *env, const char* lib_name) {
pubkey_class = (*env)->NewGlobalRef(env, local_pubkey_class);
const char *privkey_base = "cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey$";
- char privkey_class_name[1024]; //strlen(privkey_base) + strlen(lib_name) + 1
+ char privkey_class_name[2048] = { 0 }; //strlen(privkey_base) + strlen(lib_name) + 1
privkey_class_name[0] = 0;
strcat(privkey_class_name, privkey_base);
strcat(privkey_class_name, lib_name);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 56502da..b0b71be 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -33,7 +33,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createP
jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
double version = 1.0;
- printf("createProvider\n");
return (*env)->NewObject(env, provider_class, init, name, version, name);
}
@@ -53,12 +52,11 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_
ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
- printf("setup\n");
init_classes(env, "Mscng");
}
typedef struct {
- const char *name;
+ LPCSTR name;
ULONG bits;
} named_curve_t;
@@ -120,42 +118,94 @@ static const named_curve_t* lookup_curve(const char *name) {
}
static const named_curve_t* lookup_curve_bits(jint bitsize) {
- printf("looking up %i\n", bitsize);
for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
- printf("trying (%s, %i)\n", named_curves[i].name, named_curves[i].bits);
if (bitsize == named_curves[i].bits) {
- printf("got it!\n");
return &named_curves[i];
}
}
return NULL;
}
+static ULONG utf_16to8(NPSTR *out_buf, LPCWSTR in_str) {
+ INT result = WideCharToMultiByte(CP_UTF8, 0, in_str, -1, NULL, 0, NULL, NULL);
+ *out_buf = calloc(result, 1);
+ return WideCharToMultiByte(CP_UTF8, 0, in_str, -1, *out_buf, result, NULL, NULL);
+}
+
+static ULONG utf_8to16(NWPSTR *out_buf, LPCSTR in_str) {
+ INT result = MultiByteToWideChar(CP_UTF8, 0, in_str, -1, NULL, 0);
+ *out_buf = calloc(result * sizeof(WCHAR), 1);
+ return MultiByteToWideChar(CP_UTF8, 0, in_str, -1, *out_buf, result);
+}
+
+// Convert Java String to UTF-16 LPCWSTR null-terminated.
+// Returns: Length of LPCWSTR in bytes!
+static ULONG utf_strto16(NWPSTR *out_buf, JNIEnv *env, jobject str) {
+ jsize len = (*env)->GetStringLength(env, str);
+ *out_buf = calloc(len * sizeof(jchar) + 1, 1);
+ const jchar *chars = (*env)->GetStringChars(env, str, NULL);
+ memcpy(*out_buf, chars, len * sizeof(jchar));
+ (*env)->ReleaseStringChars(env, str, chars);
+ return len * sizeof(jchar);
+}
+
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurves(JNIEnv *env, jobject self) {
- jclass hash_set_class = (*env)->FindClass(env, "java/util/TreeSet");
+ jclass hash_set_class = (*env)->FindClass(env, "java/util/TreeSet");
- jmethodID hash_set_ctr = (*env)->GetMethodID(env, hash_set_class, "", "()V");
- jmethodID hash_set_add = (*env)->GetMethodID(env, hash_set_class, "add", "(Ljava/lang/Object;)Z");
+ jmethodID hash_set_ctr = (*env)->GetMethodID(env, hash_set_class, "", "()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);
+ jobject result = (*env)->NewObject(env, hash_set_class, hash_set_ctr);
- for (size_t i = 0; i < sizeof(named_curves)/sizeof(named_curve_t); ++i) {
- jstring curve_name = (*env)->NewStringUTF(env, named_curves[i].name);
- (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name);
- }
- printf("getCurves\n");
+ NTSTATUS status;
+ BCRYPT_ALG_HANDLE handle;
+
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&handle, BCRYPT_ECDH_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return 0;
+ }
+
+ ULONG bufSize;
+ if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, NULL, 0, &bufSize, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptGetProperty(length only)\n", status);
+ return 0;
+ }
+
+ BCRYPT_ECC_CURVE_NAMES *curves = (BCRYPT_ECC_CURVE_NAMES *)calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, (PBYTE) curves, bufSize, &bufSize, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptGetProperty(whole)\n", status);
+ return 0;
+ }
+ for (size_t i = 0; i < curves->dwEccCurveNames; ++i) {
+ NPSTR curve_name;
+ ULONG len = utf_16to8(&curve_name, curves->pEccCurveNames[i]);
+ jstring c_name = (*env)->NewStringUTF(env, curve_name);
+ (*env)->CallBooleanMethod(env, result, hash_set_add, c_name);
+ free(curve_name);
+ }
+
+ free(curves);
+
+ BCryptCloseAlgorithmProvider(handle, 0);
return result;
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
- printf("keysizeSupported\n");
- return (lookup_curve_bits(keysize) == NULL) ? JNI_FALSE : JNI_TRUE;
+ switch (keysize) {
+ case 256:
+ case 384:
+ case 521:
+ return JNI_TRUE;
+ default:
+ return JNI_FALSE;
+ }
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported(JNIEnv *env, jobject self, jobject params) {
- printf("paramsSupported\n");
if (params == NULL) {
- printf("theyNull\n");
return JNI_FALSE;
}
@@ -203,41 +253,20 @@ static void biginteger_to_bytes(JNIEnv *env, jobject bigint, PBYTE bytes, ULONG
(*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
}
-static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, ULONG paramLength) {
- // Taken from https://github.com/dotnet/corefx, thanks! This API is nowhere to be found.
+static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, PULONG paramLength) {
//
- // BCRYPT_ECC_PARAMETER_HEADER header
- // byte[cbFieldLength] P
- // byte[cbFieldLength] A
- // byte[cbFieldLength] B
- // byte[cbFieldLength] G.X
- // byte[cbFieldLength] G.Y
- // byte[cbSubgroupOrder] Order (n)
- // byte[cbCofactor] Cofactor (h)
- // byte[cbSeed] Seed
-
- // BCRYPT_ECC_PARAMETER_HEADER
- // internal int Version; //Version of the structure
- // internal ECC_CURVE_TYPE_ENUM CurveType; //Supported curve types.
- // internal ECC_CURVE_ALG_ID_ENUM CurveGenerationAlgId; //For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
- // internal int cbFieldLength; //Byte length of the fields P, A, B, X, Y.
- // internal int cbSubgroupOrder; //Byte length of the subgroup.
- // internal int cbCofactor; //Byte length of cofactor of G in E.
- // internal int cbSeed; //Byte length of the seed used to generate the curve.
-
- // internal enum ECC_CURVE_TYPE_ENUM : int
- // {
- // BCRYPT_ECC_PRIME_SHORT_WEIERSTRASS_CURVE = 0x1,
- // BCRYPT_ECC_PRIME_TWISTED_EDWARDS_CURVE = 0x2,
- // BCRYPT_ECC_PRIME_MONTGOMERY_CURVE = 0x3,
- // }
-
- // internal enum ECC_CURVE_ALG_ID_ENUM : int
- // {
- // BCRYPT_NO_CURVE_GENERATION_ALG_ID = 0x0,
- // }
- BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)eccParams;
- PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
+ // BCRYPT_ECCFULLKEY_BLOB header
+ // P[cbFieldLength] Prime specifying the base field.
+ // A[cbFieldLength] Coefficient A of the equation y^2 = x^3 + A*x + B mod p
+ // B[cbFieldLength] Coefficient B of the equation y^2 = x^3 + A*x + B mod p
+ // Gx[cbFieldLength] X-coordinate of the base point.
+ // Gy[cbFieldLength] Y-coordinate of the base point.
+ // n[cbSubgroupOrder] Order of the group generated by G = (x,y)
+ // h[cbCofactor] Cofactor of G in E.
+ // S[cbSeed] Seed of the curve.
+
+ BCRYPT_ECCFULLKEY_BLOB *header = (BCRYPT_ECCFULLKEY_BLOB*)eccParams;
+ PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECCFULLKEY_BLOB)];
//cbFieldLength
PBYTE P = paramsStart;
@@ -255,6 +284,8 @@ static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, ULONG paramLen
//cbSeed
PBYTE S = H + header->cbCofactor;
+ *paramLength = sizeof(BCRYPT_ECCFULLKEY_BLOB) + 5 * header->cbFieldLength + header->cbSubgroupOrder + header->cbCofactor + header->cbSeed;
+
jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "", "(Ljava/math/BigInteger;)V");
@@ -322,7 +353,7 @@ static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
jint order_bytes = (order_bits + 7) / 8;
// header_size + 5*bytes + order_bytes + cof_size + 0
- ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5*bytes + order_bytes + sizeof(jint) + 0;
+ ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5*bytes + order_bytes + 1 + 0;
*curve = calloc(bufSize, 1);
BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
header->dwVersion = 1;
@@ -330,7 +361,7 @@ static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
header->dwCurveGenerationAlgId = 0;
header->cbFieldLength = bytes;
header->cbSubgroupOrder = order_bytes;
- header->cbCofactor = sizeof(jint);
+ header->cbCofactor = 1;
header->cbSeed = 0;
PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
@@ -341,14 +372,16 @@ static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
biginteger_to_bytes(env, gx, paramsStart + 3*bytes, bytes);
biginteger_to_bytes(env, gy, paramsStart + 4*bytes, bytes);
biginteger_to_bytes(env, n, paramsStart + 5*bytes, order_bytes);
- jint *cof_ptr = (jint *) (paramsStart + 5*bytes + order_bytes);
- *cof_ptr = h;
+ PBYTE cof_ptr = (PBYTE) (paramsStart + 5*bytes + order_bytes);
+ *cof_ptr = (BYTE)h;
return bufSize;
}
static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
- if (NT_FAILURE(BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ NTSTATUS status;
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
//err
+ wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
return 0;
}
ULONG result = 0;
@@ -359,17 +392,22 @@ static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, job
PUCHAR chars = calloc(utf_length + 1, 1);
(*env)->GetStringUTFRegion(env, name, 0, utf_length, chars);
const named_curve_t *curve = lookup_curve(chars);
- if (NT_FAILURE(BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, chars, strlen(chars), 0))) {
+ NWPSTR curve_utf16;
+ ULONG ret = utf_8to16(&curve_utf16, chars);
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR) curve_utf16, ret * sizeof(WCHAR), 0))) {
//err
+ wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
return 0;
}
free(chars);
+ free(curve_utf16);
result = curve->bits;
} else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
PBYTE curve;
ULONG curveLen = create_curve(env, params, &curve);
- if (NT_FAILURE(BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
//err
+ wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
return 0;
}
free(curve);
@@ -382,31 +420,62 @@ static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, job
jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
jint bits = (*env)->CallIntMethod(env, field, get_bits);
- result = (bits + 7) / 8;
+ result = bits;
}
return result;
}
-static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
+static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
+ NTSTATUS status;
ULONG bufSize = 0;
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
//err
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, length only)\n", status);
+ return NULL;
}
if (bufSize == 0) {
//err
+ printf("err0\n");
+ return NULL;
}
- PBYTE privBuf = calloc(bufSize, 1);
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufSize, &bufSize, 0))) {
+ PBYTE fullBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, fullBuf, bufSize, &bufSize, 0))) {
//err
- }
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, whole)\n", status);
+ return NULL;
+ }
+
+ ULONG paramLength;
+ jobject ec_priv_param_spec = create_ec_param_spec(env, fullBuf, ¶mLength);
+ free(fullBuf);
+
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(length only)\n", status);
+ return NULL;
+ }
+
+ PBYTE privBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufSize, &bufSize, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(whole)\n", status);
+ return NULL;
+ }
+
+ printf("generate length %lu\n", bufSize);
+ printf("generated privkey: ");
+ for (size_t i = 0; i < bufSize; ++i) {
+ printf("%02x", (unsigned)privBuf[i] & 0xffU);
+ }
+ printf("\n");
// privBuf looks like:
- // BCRYPT_ECCKEY_BLOB header
- // byte[cbKey] Q.X
- // byte[cbKey] Q.Y
- // byte[cbKey] D
- BCRYPT_ECCKEY_BLOB *privHeader = (BCRYPT_ECCKEY_BLOB*)privBuf;
+ // BCRYPT_ECCKEY_BLOB header
+ // Qx[cbKey] X-coordinate of the public point.
+ // Qy[cbKey] Y-coordinate of the public point.
+ // d[cbKey] Private key.
+ BCRYPT_ECCKEY_BLOB *privHeader = (BCRYPT_ECCKEY_BLOB*)privBuf;
PBYTE priv_x = &privBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
PBYTE priv_y = priv_x + privHeader->cbKey;
PBYTE priv = priv_y + privHeader->cbKey;
@@ -432,28 +501,54 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_par
(*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
free(privBuf);
-
- jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
- jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[BLjava/security/spec/ECParameterSpec;)V");
+
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[B[B[BLjava/security/spec/ECParameterSpec;)V");
return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
}
-static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_param_spec) {
+static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
+ NTSTATUS status;
ULONG bufSize = 0;
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
//err
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, length only)\n", status);
+ return NULL;
}
+ if (bufSize == 0) {
+ //err
+ printf("err0\n");
+ return NULL;
+ }
- PBYTE pubBuf = calloc(bufSize, 1);
- if (NT_FAILURE(BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, pubBuf, bufSize, &bufSize, 0))) {
+ PBYTE fullBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, fullBuf, bufSize, &bufSize, 0))) {
//err
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, whole)\n", status);
+ return NULL;
}
- // pubBuf looks like:
- // BCRYPT_ECCKEY_BLOB header
- // byte[cbKey] Q.X
- // byte[cbKey] Q.Y
- BCRYPT_ECCKEY_BLOB *pubHeader = (BCRYPT_ECCKEY_BLOB*)pubBuf;
+ ULONG paramLength;
+ jobject ec_pub_param_spec = create_ec_param_spec(env, fullBuf, ¶mLength);
+ free(fullBuf);
+
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(length only)\n", status);
+ return NULL;
+ }
+
+ PBYTE pubBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, pubBuf, bufSize, &bufSize, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(whole)\n", status);
+ return NULL;
+ }
+
+ // pubBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // Qx[cbKey] X-coordinate of the public point.
+ // Qy[cbKey] Y-coordinate of the public point.
+ BCRYPT_ECCKEY_BLOB *pubHeader = (BCRYPT_ECCKEY_BLOB*)pubBuf;
PBYTE pub_x = &pubBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
PBYTE pub_y = pub_x + pubHeader->cbKey;
@@ -474,22 +569,85 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jobject ec_para
free(pubBuf);
- jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
}
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
- throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
- return NULL;
+ NTSTATUS status;
+ BCRYPT_ALG_HANDLE handle = NULL;
+
+ jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring)(*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR algo;
+ if (strcmp(type_data, "ECDH") == 0) {
+ switch (keysize) {
+ case 256:
+ algo = BCRYPT_ECDH_P256_ALGORITHM;
+ break;
+ case 384:
+ algo = BCRYPT_ECDH_P384_ALGORITHM;
+ break;
+ case 521:
+ algo = BCRYPT_ECDH_P521_ALGORITHM;
+ break;
+ default:
+ //err
+ break;
+ }
+ } else if (strcmp(type_data, "ECDSA") == 0) {
+ switch (keysize) {
+ case 256:
+ algo = BCRYPT_ECDSA_P256_ALGORITHM;
+ break;
+ case 384:
+ algo = BCRYPT_ECDSA_P384_ALGORITHM;
+ break;
+ case 521:
+ algo = BCRYPT_ECDSA_P521_ALGORITHM;
+ break;
+ default:
+ //err
+ break;
+ }
+ } else {
+ //err
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return NULL;
+ }
+
+ BCRYPT_KEY_HANDLE key = NULL;
+
+ if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, keysize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptGenerateKeyPair\n", status);
+ }
+
+ if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
+ }
+
+ jobject privkey = key_to_privkey(env, key);
+ jobject pubkey = key_to_pubkey(env, key);
+
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+
+ BCryptDestroyKey(key);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
- BCRYPT_ALG_HANDLE kaHandle = NULL;
+ NTSTATUS status;
+ BCRYPT_ALG_HANDLE handle = NULL;
BCRYPT_KEY_HANDLE key = NULL;
- fprintf(stderr, "1\n");
- fflush(stderr);
jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
@@ -500,74 +658,37 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
} else if (strcmp(type_data, "ECDSA") == 0) {
algo = BCRYPT_ECDSA_ALGORITHM;
} else {
- fprintf(stderr, "err\n");
- fflush(stderr);
+ //err
}
(*env)->ReleaseStringUTFChars(env, type, type_data);
- fprintf(stderr, "2\n");
- fflush(stderr);
- ULONG bits = init_algo(env, &kaHandle, algo, params);
+ ULONG bits = init_algo(env, &handle, algo, params);
if (bits == 0) {
- fprintf(stderr, "err0\n");
- fflush(stderr);
- }
-
- fprintf(stderr, "3\n");
- fflush(stderr);
- ULONG paramsSize;
- if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, NULL, 0, ¶msSize, 0))) {
- fprintf(stderr, "err\n");
- fflush(stderr);
- }
- if (paramsSize == 0) {
- fprintf(stderr, "err0\n");
- fflush(stderr);
- }
-
- fprintf(stderr, "4\n");
- fflush(stderr);
- PBYTE eccParams = calloc(paramsSize, 1);
- if (NT_FAILURE(BCryptGetProperty(kaHandle, BCRYPT_ECC_PARAMETERS, eccParams, paramsSize, ¶msSize, 0))) {
- fprintf(stderr, "err\n");
- fflush(stderr);
+ //err
}
- jobject ec_param_spec = create_ec_param_spec(env, eccParams, paramsSize);
-
- free(eccParams);
-
- fprintf(stderr, "5\n");
- fflush(stderr);
- if (NT_FAILURE(BCryptGenerateKeyPair(kaHandle, &key, bits, 0))) {
- fprintf(stderr, "err\n");
- fflush(stderr);
+ if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, bits, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptGenerateKeyPair\n", status);
}
- fprintf(stderr, "6\n");
- fflush(stderr);
- if (NT_FAILURE(BCryptFinalizeKeyPair(key, 0))) {
- fprintf(stderr, "err\n");
- fflush(stderr);
+ if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
}
- jobject privkey = key_to_privkey(env, key, ec_param_spec);
- jobject pubkey = key_to_pubkey(env, key, ec_param_spec);
+ jobject privkey = key_to_privkey(env, key);
+ jobject pubkey = key_to_pubkey(env, key);
- fprintf(stderr, "7\n");
- fflush(stderr);
jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
- fprintf(stderr, "8\n");
- fflush(stderr);
BCryptDestroyKey(key);
- BCryptCloseAlgorithmProvider(kaHandle, 0);
- fprintf(stderr, "9\n");
- fflush(stderr);
+ BCryptCloseAlgorithmProvider(handle, 0);
return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+ NTSTATUS status;
+ printf("generateSecret!\n");
+
jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
@@ -597,22 +718,22 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
jint pub_length = (*env)->GetArrayLength(env, pubkey);
jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(pub)\n", status);
}
(*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
jint priv_length = (*env)->GetArrayLength(env, privkey);
jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(priv)\n", status);
}
(*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
BCRYPT_SECRET_HANDLE ka = NULL;
- if (NT_FAILURE(BCryptSecretAgreement(skey, pkey, &ka, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptSecretAgreement(skey, pkey, &ka, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptSecretAgreement\n", status);
}
BCryptBufferDesc paramList = {0};
@@ -626,13 +747,13 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
//TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
ULONG bufSize = 0;
- if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, NULL, 0, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, NULL, 0, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptDeriveKey(length only)\n", status);
}
PBYTE derived = calloc(bufSize, 1);
- if (NT_FAILURE(BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, derived, bufSize, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, derived, bufSize, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptDeriveKey(whole)\n", status);
}
jbyteArray result = (*env)->NewByteArray(env, bufSize);
@@ -671,32 +792,34 @@ static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) {
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
+ NTSTATUS status;
LPCWSTR hash_algo = get_sighash_algo(env, self);
BCRYPT_ALG_HANDLE sigHandle = NULL;
if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
//err
+ printf("init err!\n");
}
BCRYPT_ALG_HANDLE hashHandle = NULL;
- if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
}
DWORD dummy = 0;
DWORD hash_len = 0;
- if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
}
PBYTE hash = calloc(hash_len, 1);
jint data_len = (*env)->GetArrayLength(env, data);
jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- //err
+ if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ wprintf(L"**** Error 0x%x returned by BCryptHash\n", status);
}
(*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
@@ -704,20 +827,27 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
jint priv_length = (*env)->GetArrayLength(env, privkey);
jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- //err
+
+ printf("priv_length %i\n", priv_length);
+ printf("using privkey: ");
+ for (size_t i = 0; i < priv_length; ++i) {
+ printf("%02x", (unsigned)priv_data[i] & 0xffU);
+ }
+ printf("\n");
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
}
(*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
DWORD sig_len = 0;
- if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptSignHash(len only)\n", status);
}
jbyteArray sig = (*env)->NewByteArray(env, sig_len);
jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
- if (NT_FAILURE(BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptSignHash(do)\n", status);
}
(*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
@@ -731,6 +861,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) {
+ NTSTATUS status;
LPCWSTR hash_algo = get_sighash_algo(env, self);
BCRYPT_ALG_HANDLE sigHandle = NULL;
@@ -741,22 +872,22 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
BCRYPT_ALG_HANDLE hashHandle = NULL;
- if (NT_FAILURE(BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
}
DWORD dummy = 0;
DWORD hash_len = 0;
- if (NT_FAILURE(BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
}
PBYTE hash = calloc(hash_len, 1);
jint data_len = (*env)->GetArrayLength(env, data);
jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- //err
+ if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ wprintf(L"**** Error 0x%x returned by BCryptHash\n", status);
}
(*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
@@ -764,8 +895,15 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jint pub_length = (*env)->GetArrayLength(env, pubkey);
jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &pkey, pub_data, pub_length, 0))) {
- //err
+
+ printf("pub_length %i\n", pub_length);
+ printf("using pubkey: ");
+ for (size_t i = 0; i < pub_length; ++i) {
+ printf("%02x", (unsigned)pub_data[i] & 0xffU);
+ }
+ printf("\n");
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
}
(*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
@@ -785,7 +923,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
} else if (result == STATUS_INVALID_SIGNATURE) {
return JNI_FALSE;
} else {
- //err
+ wprintf(L"**** Error 0x%x returned by BCryptVerifySignature\n", status);
return JNI_FALSE;
}
}
\ No newline at end of file
--
cgit v1.3.1
From 9bc30bf9727cda5a6a78668843b01c689e25bc18 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Fri, 27 Jul 2018 22:37:53 +0200
Subject: Get Mscng signatures to work (partially).
---
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 156 +++++++++--------------
1 file changed, 63 insertions(+), 93 deletions(-)
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index b0b71be..04b0fcf 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -448,59 +448,46 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
ULONG paramLength;
jobject ec_priv_param_spec = create_ec_param_spec(env, fullBuf, ¶mLength);
- free(fullBuf);
-
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptExportKey(length only)\n", status);
- return NULL;
- }
-
- PBYTE privBuf = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, privBuf, bufSize, &bufSize, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptExportKey(whole)\n", status);
- return NULL;
- }
- printf("generate length %lu\n", bufSize);
- printf("generated privkey: ");
- for (size_t i = 0; i < bufSize; ++i) {
- printf("%02x", (unsigned)privBuf[i] & 0xffU);
- }
- printf("\n");
-
- // privBuf looks like:
- // BCRYPT_ECCKEY_BLOB header
- // Qx[cbKey] X-coordinate of the public point.
- // Qy[cbKey] Y-coordinate of the public point.
- // d[cbKey] Private key.
- BCRYPT_ECCKEY_BLOB *privHeader = (BCRYPT_ECCKEY_BLOB*)privBuf;
- PBYTE priv_x = &privBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
- PBYTE priv_y = priv_x + privHeader->cbKey;
- PBYTE priv = priv_y + privHeader->cbKey;
-
- jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ // fullBuf looks like:
+ // BCRYPT_ECCFULLKEY_BLOB header
+ // P[cbFieldLength] Prime specifying the base field.
+ // A[cbFieldLength] Coefficient A of the equation y^2 = x^3 + A*x + B mod p
+ // B[cbFieldLength] Coefficient B of the equation y^2 = x^3 + A*x + B mod p
+ // Gx[cbFieldLength] X-coordinate of the base point.
+ // Gy[cbFieldLength] Y-coordinate of the base point.
+ // n[cbSubgroupOrder] Order of the group generated by G = (x,y)
+ // h[cbCofactor] Cofactor of G in E.
+ // S[cbSeed] Seed of the curve.
+ // Qx[cbFieldLength] X-coordinate of the public point.
+ // Qy[cbFieldLength] Y-coordinate of the public point.
+ // d[cbSubgroupOrder] Private key.
+ BCRYPT_ECCFULLKEY_BLOB *privHeader = (BCRYPT_ECCFULLKEY_BLOB*)fullBuf;
+ PBYTE priv_x = &fullBuf[paramLength];
+ PBYTE priv_y = priv_x + privHeader->cbFieldLength;
+ PBYTE priv = priv_y + privHeader->cbFieldLength;
+
+ jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, privHeader, sizeof(BCRYPT_ECCKEY_BLOB));
+ memcpy(header_data, privHeader, paramLength);
(*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
- jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, priv_x, privHeader->cbKey);
+ memcpy(x_data, priv_x, privHeader->cbFieldLength);
(*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
- jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, priv_y, privHeader->cbKey);
+ memcpy(y_data, priv_y, privHeader->cbFieldLength);
(*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
- jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbKey);
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbSubgroupOrder);
jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
- memcpy(key_priv, priv, privHeader->cbKey);
+ memcpy(key_priv, priv, privHeader->cbSubgroupOrder);
(*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
- free(privBuf);
+ free(fullBuf);
jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[B[B[BLjava/security/spec/ECParameterSpec;)V");
return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
@@ -529,45 +516,39 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
ULONG paramLength;
jobject ec_pub_param_spec = create_ec_param_spec(env, fullBuf, ¶mLength);
- free(fullBuf);
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptExportKey(length only)\n", status);
- return NULL;
- }
-
- PBYTE pubBuf = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, pubBuf, bufSize, &bufSize, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptExportKey(whole)\n", status);
- return NULL;
- }
-
- // pubBuf looks like:
- // BCRYPT_ECCKEY_BLOB header
- // Qx[cbKey] X-coordinate of the public point.
- // Qy[cbKey] Y-coordinate of the public point.
- BCRYPT_ECCKEY_BLOB *pubHeader = (BCRYPT_ECCKEY_BLOB*)pubBuf;
- PBYTE pub_x = &pubBuf[sizeof(BCRYPT_ECCKEY_BLOB)];
- PBYTE pub_y = pub_x + pubHeader->cbKey;
+ // fullBuf looks like:
+ // BCRYPT_ECCFULLKEY_BLOB header
+ // P[cbFieldLength] Prime specifying the base field.
+ // A[cbFieldLength] Coefficient A of the equation y^2 = x^3 + A*x + B mod p
+ // B[cbFieldLength] Coefficient B of the equation y^2 = x^3 + A*x + B mod p
+ // Gx[cbFieldLength] X-coordinate of the base point.
+ // Gy[cbFieldLength] Y-coordinate of the base point.
+ // n[cbSubgroupOrder] Order of the group generated by G = (x,y)
+ // h[cbCofactor] Cofactor of G in E.
+ // S[cbSeed] Seed of the curve.
+ // Qx[cbFieldLength] X-coordinate of the public point.
+ // Qy[cbFieldLength] Y-coordinate of the public point.
+ BCRYPT_ECCFULLKEY_BLOB *pubHeader = (BCRYPT_ECCFULLKEY_BLOB*)fullBuf;
+ PBYTE pub_x = &fullBuf[paramLength];
+ PBYTE pub_y = pub_x + pubHeader->cbFieldLength;
- jbyteArray header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, pubHeader, sizeof(BCRYPT_ECCKEY_BLOB));
+ memcpy(header_data, pubHeader, paramLength);
(*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
- jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
+ jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, pub_x, pubHeader->cbKey);
+ memcpy(x_data, pub_x, pubHeader->cbFieldLength);
(*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
- jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbKey);
+ jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, pub_y, pubHeader->cbKey);
+ memcpy(y_data, pub_y, pubHeader->cbFieldLength);
(*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
- free(pubBuf);
+ free(fullBuf);
jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
@@ -718,14 +699,14 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
jint pub_length = (*env)->GetArrayLength(env, pubkey);
jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(pub)\n", status);
}
(*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
jint priv_length = (*env)->GetArrayLength(env, privkey);
jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(priv)\n", status);
}
(*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
@@ -797,10 +778,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
BCRYPT_ALG_HANDLE sigHandle = NULL;
- if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
- //err
- printf("init err!\n");
- }
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return 0;
+ }
BCRYPT_ALG_HANDLE hashHandle = NULL;
@@ -827,14 +809,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
jint priv_length = (*env)->GetArrayLength(env, privkey);
jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
-
- printf("priv_length %i\n", priv_length);
- printf("using privkey: ");
- for (size_t i = 0; i < priv_length; ++i) {
- printf("%02x", (unsigned)priv_data[i] & 0xffU);
- }
- printf("\n");
- if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
}
(*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
@@ -866,9 +841,11 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
BCRYPT_ALG_HANDLE sigHandle = NULL;
- if (!init_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, params)) {
- //err
- }
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
+ //err
+ wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return 0;
+ }
BCRYPT_ALG_HANDLE hashHandle = NULL;
@@ -895,14 +872,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jint pub_length = (*env)->GetArrayLength(env, pubkey);
jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
-
- printf("pub_length %i\n", pub_length);
- printf("using pubkey: ");
- for (size_t i = 0; i < pub_length; ++i) {
- printf("%02x", (unsigned)pub_data[i] & 0xffU);
- }
- printf("\n");
- if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
}
(*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
--
cgit v1.3.1
From 0582131bbcabea050f6a43643b7e81e922e3acd0 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sat, 28 Jul 2018 11:45:49 +0200
Subject: Proper error handling in Mscng.
---
src/cz/crcs/ectester/standalone/libs/jni/c_utils.c | 10 +
src/cz/crcs/ectester/standalone/libs/jni/c_utils.h | 5 +
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 1054 +++++++++++---------
3 files changed, 570 insertions(+), 499 deletions(-)
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
index f920fc4..6954c36 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
@@ -1,4 +1,5 @@
#include "c_utils.h"
+#define _ISOC99_SOURCE
#include
jclass ec_parameter_spec_class;
@@ -64,3 +65,12 @@ void throw_new(JNIEnv *env, const char *class, const char *message) {
jclass clazz = (*env)->FindClass(env, class);
(*env)->ThrowNew(env, clazz, message);
}
+
+void throw_new_var(JNIEnv *env, const char *class, const char *format, ...) {
+ char buffer[2048];
+ va_list args;
+ va_start(args, format);
+ int res = vsnprintf(buffer, 2048, format, args);
+ va_end(args);
+ throw_new(env, class, buffer);
+}
\ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h
index 3ef8f86..2e5fa1a 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h
@@ -27,6 +27,11 @@ void init_classes(JNIEnv *env, const char* lib_name);
*/
void throw_new(JNIEnv *env, const char *class, const char *message);
+/**
+ * Throw a new exception of class, with formatted message.
+ */
+void throw_new_var(JNIEnv *env, const char *class, const char *format, ...);
+
/**
* Some useful defines to init the provider.
*/
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 04b0fcf..12cc13d 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -24,97 +24,97 @@ typedef struct {
ULONG cbSeed; //Byte length of the seed used to generate the curve.
} BCRYPT_ECC_PARAMETER_HEADER;
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self){
- jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
- provider_class = (*env)->NewGlobalRef(env, local_provider_class);
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self) {
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
+ provider_class = (*env)->NewGlobalRef(env, local_provider_class);
- jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V");
+ jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V");
- jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
- double version = 1.0;
+ jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
+ double version = 1.0;
- return (*env)->NewObject(env, provider_class, init, name, version, name);
+ return (*env)->NewObject(env, provider_class, init, name, version, name);
}
JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup(JNIEnv *env, jobject self) {
- INIT_PROVIDER(env, provider_class);
+ INIT_PROVIDER(env, provider_class);
- ADD_KPG(env, self, "ECDH", "MscngECDH");
- ADD_KPG(env, self, "ECDSA", "MscngECDSA");
+ ADD_KPG(env, self, "ECDH", "MscngECDH");
+ ADD_KPG(env, self, "ECDSA", "MscngECDSA");
- ADD_KA(env, self, "ECDHwithSHA1KDF", "MscngECDHwithSHA1KDF");
- ADD_KA(env, self, "ECDHwithSHA256KDF", "MscngECDHwithSHA256KDF");
- ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
- ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
+ ADD_KA(env, self, "ECDHwithSHA1KDF", "MscngECDHwithSHA1KDF");
+ ADD_KA(env, self, "ECDHwithSHA256KDF", "MscngECDHwithSHA256KDF");
+ ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
+ ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
- ADD_SIG(env, self, "SHA1withECDSA", "MscngECDSAwithSHA1");
- ADD_SIG(env, self, "SHA256withECDSA", "MscngECDSAwithSHA256");
- ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
- ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
+ ADD_SIG(env, self, "SHA1withECDSA", "MscngECDSAwithSHA1");
+ ADD_SIG(env, self, "SHA256withECDSA", "MscngECDSAwithSHA256");
+ ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
+ ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
- init_classes(env, "Mscng");
+ init_classes(env, "Mscng");
}
typedef struct {
- LPCSTR name;
- ULONG bits;
+ LPCSTR name;
+ ULONG bits;
} named_curve_t;
static named_curve_t named_curves[] = {
- {"curve25519", 256},
- {"brainpoolP160r1", 160},
- {"brainpoolP160t1", 160},
- {"brainpoolP192r1", 192},
- {"brainpoolP192t1", 192},
- {"brainpoolP224r1", 224},
- {"brainpoolP224t1", 224},
- {"brainpoolP256r1", 256},
- {"brainpoolP256t1", 256},
- {"brainpoolP320r1", 320},
- {"brainpoolP320t1", 320},
- {"brainpoolP384r1", 384},
- {"brainpoolP384t1", 384},
- {"brainpoolP512r1", 512},
- {"brainpoolP512t1", 512},
- {"ec192wapi", 192},
- {"nistP192", 192},
- {"nistP224", 224},
- {"nistP256", 256},
- {"nistP384", 384},
- {"nistP521", 521},
- {"numsP256t1", 256},
- {"numsP384t1", 384},
- {"numsP512t1", 512},
- {"secP160k1", 160},
- {"secP160r1", 160},
- {"secP160r2", 160},
- {"secP192k1", 192},
- {"secP192r1", 192},
- {"secP224k1", 224},
- {"secP224r1", 224},
- {"secP256k1", 256},
- {"secP256r1", 256},
- {"secP384r1", 384},
- {"secP521r1", 521},
- {"wtls12", 224},
- {"wtls7", 160},
- {"wtls9", 160},
- {"x962P192v1", 192},
- {"x962P192v2", 192},
- {"x962P192v3", 192},
- {"x962P239v1", 239},
- {"x962P239v2", 239},
- {"x962P239v3", 239},
- {"x962P256v1", 256}
+ {"curve25519", 256},
+ {"brainpoolP160r1", 160},
+ {"brainpoolP160t1", 160},
+ {"brainpoolP192r1", 192},
+ {"brainpoolP192t1", 192},
+ {"brainpoolP224r1", 224},
+ {"brainpoolP224t1", 224},
+ {"brainpoolP256r1", 256},
+ {"brainpoolP256t1", 256},
+ {"brainpoolP320r1", 320},
+ {"brainpoolP320t1", 320},
+ {"brainpoolP384r1", 384},
+ {"brainpoolP384t1", 384},
+ {"brainpoolP512r1", 512},
+ {"brainpoolP512t1", 512},
+ {"ec192wapi", 192},
+ {"nistP192", 192},
+ {"nistP224", 224},
+ {"nistP256", 256},
+ {"nistP384", 384},
+ {"nistP521", 521},
+ {"numsP256t1", 256},
+ {"numsP384t1", 384},
+ {"numsP512t1", 512},
+ {"secP160k1", 160},
+ {"secP160r1", 160},
+ {"secP160r2", 160},
+ {"secP192k1", 192},
+ {"secP192r1", 192},
+ {"secP224k1", 224},
+ {"secP224r1", 224},
+ {"secP256k1", 256},
+ {"secP256r1", 256},
+ {"secP384r1", 384},
+ {"secP521r1", 521},
+ {"wtls12", 224},
+ {"wtls7", 160},
+ {"wtls9", 160},
+ {"x962P192v1", 192},
+ {"x962P192v2", 192},
+ {"x962P192v3", 192},
+ {"x962P239v1", 239},
+ {"x962P239v2", 239},
+ {"x962P239v3", 239},
+ {"x962P256v1", 256}
};
static const named_curve_t* lookup_curve(const char *name) {
- for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
- if (strcmp(name, named_curves[i].name) == 0) {
- return &named_curves[i];
- }
- }
- return NULL;
+ for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
+ if (strcmp(name, named_curves[i].name) == 0) {
+ return &named_curves[i];
+ }
+ }
+ return NULL;
}
static const named_curve_t* lookup_curve_bits(jint bitsize) {
@@ -161,24 +161,25 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurv
BCRYPT_ALG_HANDLE handle;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&handle, BCRYPT_ECDH_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
+ return result;
}
ULONG bufSize;
if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, NULL, 0, &bufSize, 0))) {
- //err
wprintf(L"**** Error 0x%x returned by BCryptGetProperty(length only)\n", status);
- return 0;
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return result;
}
BCRYPT_ECC_CURVE_NAMES *curves = (BCRYPT_ECC_CURVE_NAMES *)calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, (PBYTE) curves, bufSize, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, (PBYTE)curves, bufSize, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptGetProperty(whole)\n", status);
- return 0;
+ BCryptCloseAlgorithmProvider(handle, 0);
+ free(curves);
+ return result;
}
+
for (size_t i = 0; i < curves->dwEccCurveNames; ++i) {
NPSTR curve_name;
ULONG len = utf_16to8(&curve_name, curves->pEccCurveNames[i]);
@@ -190,7 +191,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurv
free(curves);
BCryptCloseAlgorithmProvider(handle, 0);
- return result;
+ return result;
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
@@ -206,55 +207,55 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported(JNIEnv *env, jobject self, jobject params) {
if (params == NULL) {
- return JNI_FALSE;
- }
-
- 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);
- const named_curve_t *curve = lookup_curve(utf_name);
- (*env)->ReleaseStringUTFChars(env, name, utf_name);
- return curve == NULL ? JNI_FALSE : JNI_TRUE;
- } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
- jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
- jobject 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, curve, get_field);
-
- if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
- } else {
- return JNI_FALSE;
- }
+ return JNI_FALSE;
+ }
+
+ 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);
+ const named_curve_t *curve = lookup_curve(utf_name);
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return curve == NULL ? JNI_FALSE : JNI_TRUE;
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject 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, curve, get_field);
+
+ if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+ } else {
+ return JNI_FALSE;
+ }
}
static jobject bytes_to_biginteger(JNIEnv *env, PBYTE bytes, int len) {
- jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V");
- jbyteArray byte_array = (*env)->NewByteArray(env, len);
- jbyte *data = (*env)->GetByteArrayElements(env, byte_array, NULL);
- memcpy(data, bytes, len);
- (*env)->ReleaseByteArrayElements(env, byte_array, data, 0);
- jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, byte_array);
- return result;
+ jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V");
+ jbyteArray byte_array = (*env)->NewByteArray(env, len);
+ jbyte *data = (*env)->GetByteArrayElements(env, byte_array, NULL);
+ memcpy(data, bytes, len);
+ (*env)->ReleaseByteArrayElements(env, byte_array, data, 0);
+ jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, byte_array);
+ return result;
}
static void biginteger_to_bytes(JNIEnv *env, jobject bigint, PBYTE bytes, ULONG len) {
- jmethodID to_byte_array = (*env)->GetMethodID(env, biginteger_class, "toByteArray", "()[B");
+ 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);
- memcpy(bytes, &byte_data[byte_length - len], len);
- (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
+ 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);
+ memcpy(bytes, &byte_data[byte_length - len], len);
+ (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
}
static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, PULONG paramLength) {
- //
+ //
// BCRYPT_ECCFULLKEY_BLOB header
// P[cbFieldLength] Prime specifying the base field.
// A[cbFieldLength] Coefficient A of the equation y^2 = x^3 + A*x + B mod p
@@ -266,151 +267,148 @@ static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, PULONG paramLe
// S[cbSeed] Seed of the curve.
BCRYPT_ECCFULLKEY_BLOB *header = (BCRYPT_ECCFULLKEY_BLOB*)eccParams;
- PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECCFULLKEY_BLOB)];
+ PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECCFULLKEY_BLOB)];
- //cbFieldLength
- PBYTE P = paramsStart;
- PBYTE A = P + header->cbFieldLength;
- PBYTE B = A + header->cbFieldLength;
- PBYTE GX = B + header->cbFieldLength;
- PBYTE GY = GX + header->cbFieldLength;
+ //cbFieldLength
+ PBYTE P = paramsStart;
+ PBYTE A = P + header->cbFieldLength;
+ PBYTE B = A + header->cbFieldLength;
+ PBYTE GX = B + header->cbFieldLength;
+ PBYTE GY = GX + header->cbFieldLength;
- //cbSubgroupOrder
- PBYTE N = GY + header->cbFieldLength;
+ //cbSubgroupOrder
+ PBYTE N = GY + header->cbFieldLength;
- //cbCofactor
- PBYTE H = N + header->cbSubgroupOrder;
+ //cbCofactor
+ PBYTE H = N + header->cbSubgroupOrder;
- //cbSeed
- PBYTE S = H + header->cbCofactor;
+ //cbSeed
+ PBYTE S = H + header->cbCofactor;
*paramLength = sizeof(BCRYPT_ECCFULLKEY_BLOB) + 5 * header->cbFieldLength + header->cbSubgroupOrder + header->cbCofactor + header->cbSeed;
- jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
+ jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
- jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "", "(Ljava/math/BigInteger;)V");
- jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
+ jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "", "(Ljava/math/BigInteger;)V");
+ jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
- jobject a_int = bytes_to_biginteger(env, A, header->cbFieldLength);
- jobject b_int = bytes_to_biginteger(env, B, header->cbFieldLength);
+ jobject a_int = bytes_to_biginteger(env, A, header->cbFieldLength);
+ jobject b_int = bytes_to_biginteger(env, B, header->cbFieldLength);
- jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "", "(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);
+ jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "", "(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);
- jobject gx_int = bytes_to_biginteger(env, GX, header->cbFieldLength);
- jobject gy_int = bytes_to_biginteger(env, GY, header->cbFieldLength);
+ jobject gx_int = bytes_to_biginteger(env, GX, header->cbFieldLength);
+ jobject gy_int = bytes_to_biginteger(env, GY, header->cbFieldLength);
- jmethodID point_init = (*env)->GetMethodID(env, point_class, "", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
- jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
+ jmethodID point_init = (*env)->GetMethodID(env, point_class, "", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
- jobject n_int = bytes_to_biginteger(env, N, header->cbSubgroupOrder);
+ jobject n_int = bytes_to_biginteger(env, N, header->cbSubgroupOrder);
- jobject h_int = bytes_to_biginteger(env, H, header->cbCofactor);
- jmethodID bigint_to_int = (*env)->GetMethodID(env, biginteger_class, "intValue", "()I");
- jint cof = (*env)->CallIntMethod(env, h_int, bigint_to_int);
+ jobject h_int = bytes_to_biginteger(env, H, header->cbCofactor);
+ jmethodID bigint_to_int = (*env)->GetMethodID(env, biginteger_class, "intValue", "()I");
+ jint cof = (*env)->CallIntMethod(env, h_int, bigint_to_int);
- jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
- return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
+ jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
+ return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
}
static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
- 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_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_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_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, "getB", "()Ljava/math/BigInteger;");
- jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
+ jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
- jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
- jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
+ jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
- jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
- jobject p = (*env)->CallObjectMethod(env, field, get_p);
+ jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
+ jobject p = (*env)->CallObjectMethod(env, field, get_p);
- 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_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);
+ jmethodID get_x = (*env)->GetMethodID(env, point_class, "getAffineX", "()Ljava/math/BigInteger;");
+ jobject gx = (*env)->CallObjectMethod(env, g, get_x);
- jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
- jobject gy = (*env)->CallObjectMethod(env, g, get_y);
+ jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
+ jobject gy = (*env)->CallObjectMethod(env, g, get_y);
- jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
- jobject n = (*env)->CallObjectMethod(env, params, get_n);
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
- jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
- jint h = (*env)->CallIntMethod(env, params, get_h);
+ jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
+ jint h = (*env)->CallIntMethod(env, params, get_h);
- jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
- jint order_bits = (*env)->CallIntMethod(env, n, get_bitlength);
- jint order_bytes = (order_bits + 7) / 8;
+ jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
+ jint order_bits = (*env)->CallIntMethod(env, n, get_bitlength);
+ jint order_bytes = (order_bits + 7) / 8;
- // header_size + 5*bytes + order_bytes + cof_size + 0
- ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5*bytes + order_bytes + 1 + 0;
- *curve = calloc(bufSize, 1);
- BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
- header->dwVersion = 1;
- header->dwCurveType = 1; //1 -> Prime short Weierstrass, 2 -> Prime Twisted Edwards, 3 -> Montgomery
- header->dwCurveGenerationAlgId = 0;
- header->cbFieldLength = bytes;
- header->cbSubgroupOrder = order_bytes;
+ // header_size + 5*bytes + order_bytes + cof_size + 0
+ ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5 * bytes + order_bytes + 1 + 0;
+ *curve = calloc(bufSize, 1);
+ BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
+ header->dwVersion = 1;
+ header->dwCurveType = 1; //1 -> Prime short Weierstrass, 2 -> Prime Twisted Edwards, 3 -> Montgomery
+ header->dwCurveGenerationAlgId = 0;
+ header->cbFieldLength = bytes;
+ header->cbSubgroupOrder = order_bytes;
header->cbCofactor = 1;
- header->cbSeed = 0;
+ header->cbSeed = 0;
- PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
+ PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
- biginteger_to_bytes(env, p, paramsStart, bytes);
- biginteger_to_bytes(env, a, paramsStart + bytes, bytes);
- biginteger_to_bytes(env, b, paramsStart + 2*bytes, bytes);
- biginteger_to_bytes(env, gx, paramsStart + 3*bytes, bytes);
- biginteger_to_bytes(env, gy, paramsStart + 4*bytes, bytes);
- biginteger_to_bytes(env, n, paramsStart + 5*bytes, order_bytes);
- PBYTE cof_ptr = (PBYTE) (paramsStart + 5*bytes + order_bytes);
+ biginteger_to_bytes(env, p, paramsStart, bytes);
+ biginteger_to_bytes(env, a, paramsStart + bytes, bytes);
+ biginteger_to_bytes(env, b, paramsStart + 2 * bytes, bytes);
+ biginteger_to_bytes(env, gx, paramsStart + 3 * bytes, bytes);
+ biginteger_to_bytes(env, gy, paramsStart + 4 * bytes, bytes);
+ biginteger_to_bytes(env, n, paramsStart + 5 * bytes, order_bytes);
+ PBYTE cof_ptr = (PBYTE)(paramsStart + 5 * bytes + order_bytes);
*cof_ptr = (BYTE)h;
- return bufSize;
+ return bufSize;
}
static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
NTSTATUS status;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
- }
+ return 0;
+ }
ULONG result = 0;
- 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);
+ 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);
jint utf_length = (*env)->GetStringUTFLength(env, name);
PUCHAR chars = calloc(utf_length + 1, 1);
(*env)->GetStringUTFRegion(env, name, 0, utf_length, chars);
- const named_curve_t *curve = lookup_curve(chars);
+ const named_curve_t *curve = lookup_curve(chars);
NWPSTR curve_utf16;
ULONG ret = utf_8to16(&curve_utf16, chars);
- if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR) curve_utf16, ret * sizeof(WCHAR), 0))) {
- //err
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR)curve_utf16, ret * sizeof(WCHAR), 0))) {
wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
- return 0;
- }
+ return 0;
+ }
free(chars);
free(curve_utf16);
result = curve->bits;
- } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
- PBYTE curve;
- ULONG curveLen = create_curve(env, params, &curve);
- if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
- //err
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ PBYTE curve;
+ ULONG curveLen = create_curve(env, params, &curve);
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
- return 0;
- }
- free(curve);
+ return 0;
+ }
+ free(curve);
jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve);
@@ -421,27 +419,24 @@ static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, job
jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
jint bits = (*env)->CallIntMethod(env, field, get_bits);
result = bits;
- }
- return result;
+ }
+ return result;
}
static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
NTSTATUS status;
- ULONG bufSize = 0;
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
- //err
+ ULONG bufSize = 0;
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, length only)\n", status);
return NULL;
- }
- if (bufSize == 0) {
- //err
- printf("err0\n");
+ }
+ if (bufSize == 0) {
+ printf("buf 0\n");
return NULL;
- }
+ }
PBYTE fullBuf = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, fullBuf, bufSize, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, fullBuf, bufSize, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, whole)\n", status);
return NULL;
}
@@ -449,7 +444,7 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
ULONG paramLength;
jobject ec_priv_param_spec = create_ec_param_spec(env, fullBuf, ¶mLength);
- // fullBuf looks like:
+ // fullBuf looks like:
// BCRYPT_ECCFULLKEY_BLOB header
// P[cbFieldLength] Prime specifying the base field.
// A[cbFieldLength] Coefficient A of the equation y^2 = x^3 + A*x + B mod p
@@ -463,56 +458,53 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
// Qy[cbFieldLength] Y-coordinate of the public point.
// d[cbSubgroupOrder] Private key.
BCRYPT_ECCFULLKEY_BLOB *privHeader = (BCRYPT_ECCFULLKEY_BLOB*)fullBuf;
- PBYTE priv_x = &fullBuf[paramLength];
- PBYTE priv_y = priv_x + privHeader->cbFieldLength;
- PBYTE priv = priv_y + privHeader->cbFieldLength;
-
- jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, privHeader, paramLength);
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
-
- jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
- jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, priv_x, privHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
-
- jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
- jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, priv_y, privHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
-
- jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbSubgroupOrder);
- jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
- memcpy(key_priv, priv, privHeader->cbSubgroupOrder);
- (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
+ PBYTE priv_x = &fullBuf[paramLength];
+ PBYTE priv_y = priv_x + privHeader->cbFieldLength;
+ PBYTE priv = priv_y + privHeader->cbFieldLength;
+
+ jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, privHeader, paramLength);
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+
+ jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, priv_x, privHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+
+ jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, priv_y, privHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbSubgroupOrder);
+ jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ memcpy(key_priv, priv, privHeader->cbSubgroupOrder);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
free(fullBuf);
-
- jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[B[B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
+
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
}
static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
NTSTATUS status;
- ULONG bufSize = 0;
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
- //err
+ ULONG bufSize = 0;
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, length only)\n", status);
return NULL;
- }
+ }
if (bufSize == 0) {
- //err
printf("err0\n");
return NULL;
}
PBYTE fullBuf = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, fullBuf, bufSize, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, fullBuf, bufSize, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, whole)\n", status);
return NULL;
- }
+ }
ULONG paramLength;
jobject ec_pub_param_spec = create_ec_param_spec(env, fullBuf, ¶mLength);
@@ -530,28 +522,28 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
// Qx[cbFieldLength] X-coordinate of the public point.
// Qy[cbFieldLength] Y-coordinate of the public point.
BCRYPT_ECCFULLKEY_BLOB *pubHeader = (BCRYPT_ECCFULLKEY_BLOB*)fullBuf;
- PBYTE pub_x = &fullBuf[paramLength];
- PBYTE pub_y = pub_x + pubHeader->cbFieldLength;
+ PBYTE pub_x = &fullBuf[paramLength];
+ PBYTE pub_y = pub_x + pubHeader->cbFieldLength;
- jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, pubHeader, paramLength);
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, pubHeader, paramLength);
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
- jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
- jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, pub_x, pubHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+ jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, pub_x, pubHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
- jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
- jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, pub_y, pubHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+ jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, pub_y, pubHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
free(fullBuf);
- jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
}
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
@@ -575,8 +567,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
algo = BCRYPT_ECDH_P521_ALGORITHM;
break;
default:
- //err
- break;
+ //unreachable
+ return NULL;
}
} else if (strcmp(type_data, "ECDSA") == 0) {
switch (keysize) {
@@ -590,28 +582,32 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
algo = BCRYPT_ECDSA_P521_ALGORITHM;
break;
default:
- //err
- break;
+ //unreachable
+ return NULL;
}
} else {
- //err
+ //unreachable
+ return NULL;
}
(*env)->ReleaseStringUTFChars(env, type, type_data);
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider", status);
return NULL;
}
BCRYPT_KEY_HANDLE key = NULL;
if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, keysize, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGenerateKeyPair\n", status);
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGenerateKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
}
if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
}
jobject privkey = key_to_privkey(env, key);
@@ -624,276 +620,336 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) {
NTSTATUS status;
- BCRYPT_ALG_HANDLE handle = NULL;
- BCRYPT_KEY_HANDLE key = NULL;
-
- jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR algo;
- if (strcmp(type_data, "ECDH") == 0) {
- algo = BCRYPT_ECDH_ALGORITHM;
- } else if (strcmp(type_data, "ECDSA") == 0) {
- algo = BCRYPT_ECDSA_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
+ BCRYPT_ALG_HANDLE handle = NULL;
+ BCRYPT_KEY_HANDLE key = NULL;
+
+ jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring)(*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR algo;
+ if (strcmp(type_data, "ECDH") == 0) {
+ algo = BCRYPT_ECDH_ALGORITHM;
+ } else if (strcmp(type_data, "ECDSA") == 0) {
+ algo = BCRYPT_ECDSA_ALGORITHM;
+ } else {
+ //unreachable
+ return NULL;
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
ULONG bits = init_algo(env, &handle, algo, params);
- if (bits == 0) {
- //err
- }
+ if (bits == 0) {
+ throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
+ return NULL;
+ }
- if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, bits, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGenerateKeyPair\n", status);
- }
+ if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, bits, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGenerateKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
+ }
- if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
- }
+ if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
+ }
- jobject privkey = key_to_privkey(env, key);
- jobject pubkey = key_to_pubkey(env, key);
+ jobject privkey = key_to_privkey(env, key);
+ jobject pubkey = key_to_pubkey(env, key);
- jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
- BCryptDestroyKey(key);
- BCryptCloseAlgorithmProvider(handle, 0);
- return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+ BCryptDestroyKey(key);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
NTSTATUS status;
printf("generateSecret!\n");
- jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR kdf_algo;
- if (strcmp(type_data, "ECDHwithSHA1KDF") == 0) {
- kdf_algo = BCRYPT_SHA1_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA256KDF") == 0) {
- kdf_algo = BCRYPT_SHA256_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA384KDF") == 0) {
- kdf_algo = BCRYPT_SHA384_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA512KDF") == 0) {
- kdf_algo = BCRYPT_SHA512_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
-
- BCRYPT_ALG_HANDLE kaHandle = NULL;
-
- if (!init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params)) {
- //err
- }
-
- BCRYPT_KEY_HANDLE pkey = NULL;
- BCRYPT_KEY_HANDLE skey = NULL;
-
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(pub)\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
-
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(priv)\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
-
- BCRYPT_SECRET_HANDLE ka = NULL;
-
- if (NT_FAILURE(status = BCryptSecretAgreement(skey, pkey, &ka, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptSecretAgreement\n", status);
- }
-
- BCryptBufferDesc paramList = {0};
- BCryptBuffer kdfParams[1] = {0};
- kdfParams[0].BufferType = KDF_HASH_ALGORITHM;
- kdfParams[0].cbBuffer = (DWORD)((wcslen(kdf_algo) + 1) * sizeof(WCHAR));
- kdfParams[0].pvBuffer = (PVOID)kdf_algo;
- paramList.cBuffers = 1;
- paramList.pBuffers = kdfParams;
- paramList.ulVersion = BCRYPTBUFFER_VERSION;
-
- //TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
- ULONG bufSize = 0;
- if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, NULL, 0, &bufSize, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptDeriveKey(length only)\n", status);
- }
+ jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring)(*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR kdf_algo;
+ if (strcmp(type_data, "ECDHwithSHA1KDF") == 0) {
+ kdf_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA256KDF") == 0) {
+ kdf_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA384KDF") == 0) {
+ kdf_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA512KDF") == 0) {
+ kdf_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
+ //unreachable
+ return NULL;
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+
+ BCRYPT_ALG_HANDLE kaHandle = NULL;
+
+ ULONG bits = init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params);
+ if (bits == 0) {
+ throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
+ return NULL;
+ }
+
+ BCRYPT_KEY_HANDLE pkey = NULL;
+ BCRYPT_KEY_HANDLE skey = NULL;
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair(pub)\n", status);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair(priv)\n", status);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ BCryptDestroyKey(pkey);
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+
+ BCRYPT_SECRET_HANDLE ka = NULL;
+
+ if (NT_FAILURE(status = BCryptSecretAgreement(skey, pkey, &ka, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSecretAgreement\n", status);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ BCryptDestroyKey(pkey);
+ BCryptDestroyKey(skey);
+ return NULL;
+ }
+
+ BCryptBufferDesc paramList = { 0 };
+ BCryptBuffer kdfParams[1] = { 0 };
+ kdfParams[0].BufferType = KDF_HASH_ALGORITHM;
+ kdfParams[0].cbBuffer = (DWORD)((wcslen(kdf_algo) + 1) * sizeof(WCHAR));
+ kdfParams[0].pvBuffer = (PVOID)kdf_algo;
+ paramList.cBuffers = 1;
+ paramList.pBuffers = kdfParams;
+ paramList.ulVersion = BCRYPTBUFFER_VERSION;
+
+ //TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
+ ULONG bufSize = 0;
+ if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, NULL, 0, &bufSize, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptDeriveKey(length only)\n", status);
+ return NULL;
+ }
PBYTE derived = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, derived, bufSize, &bufSize, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptDeriveKey(whole)\n", status);
- }
+ if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, ¶mList, derived, bufSize, &bufSize, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptDeriveKey(whole)\n", status);
+ return NULL;
+ }
- jbyteArray result = (*env)->NewByteArray(env, bufSize);
- jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
- memcpy(result_data, derived, bufSize);
- (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
+ jbyteArray result = (*env)->NewByteArray(env, bufSize);
+ jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
+ memcpy(result_data, derived, bufSize);
+ (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
free(derived);
- BCryptDestroyKey(pkey);
- BCryptDestroyKey(skey);
- BCryptDestroySecret(ka);
- BCryptCloseAlgorithmProvider(kaHandle, 0);
- return result;
+ BCryptDestroyKey(pkey);
+ BCryptDestroyKey(skey);
+ BCryptDestroySecret(ka);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ return result;
}
static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) {
- jclass mscng_sig_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_sig_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR hash_algo;
- if (strcmp(type_data, "SHA1withECDSA") == 0) {
- hash_algo = BCRYPT_SHA1_ALGORITHM;
- } else if (strcmp(type_data, "SHA256withECDSA") == 0) {
- hash_algo = BCRYPT_SHA256_ALGORITHM;
- } else if (strcmp(type_data, "SHA384withECDSA") == 0) {
- hash_algo = BCRYPT_SHA384_ALGORITHM;
- } else if (strcmp(type_data, "SHA512withECDSA") == 0) {
- hash_algo = BCRYPT_SHA512_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
- return hash_algo;
+ jclass mscng_sig_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_sig_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring)(*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR hash_algo;
+ if (strcmp(type_data, "SHA1withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "SHA256withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "SHA384withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "SHA512withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
+ //unreachable
+ return NULL;
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+ return hash_algo;
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
NTSTATUS status;
- LPCWSTR hash_algo = get_sighash_algo(env, self);
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
- BCRYPT_ALG_HANDLE sigHandle = NULL;
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return NULL;
}
- BCRYPT_ALG_HANDLE hashHandle = NULL;
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- }
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ return NULL;
+ }
- DWORD dummy = 0;
- DWORD hash_len = 0;
- if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
- }
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ return NULL;
+ }
PBYTE hash = calloc(hash_len, 1);
- jint data_len = (*env)->GetArrayLength(env, data);
- jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- wprintf(L"**** Error 0x%x returned by BCryptHash\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
-
- BCRYPT_KEY_HANDLE skey = NULL;
-
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
-
- DWORD sig_len = 0;
- if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptSignHash(len only)\n", status);
- }
-
- jbyteArray sig = (*env)->NewByteArray(env, sig_len);
- jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
- if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptSignHash(do)\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptHash\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+
+ BCRYPT_KEY_HANDLE skey = NULL;
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+
+ DWORD sig_len = 0;
+ if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSignHash(len only)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ return NULL;
+ }
+
+ jbyteArray sig = (*env)->NewByteArray(env, sig_len);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSignHash(do)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
free(hash);
- BCryptDestroyKey(skey);
- BCryptCloseAlgorithmProvider(hashHandle, 0);
- BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptDestroyKey(skey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
- return sig;
+ return sig;
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) {
NTSTATUS status;
- LPCWSTR hash_algo = get_sighash_algo(env, self);
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
- BCRYPT_ALG_HANDLE sigHandle = NULL;
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return JNI_FALSE;
}
- BCRYPT_ALG_HANDLE hashHandle = NULL;
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- }
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ return JNI_FALSE;
+ }
- DWORD dummy = 0;
- DWORD hash_len = 0;
- if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
- }
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ return JNI_FALSE;
+ }
PBYTE hash = calloc(hash_len, 1);
- jint data_len = (*env)->GetArrayLength(env, data);
- jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- wprintf(L"**** Error 0x%x returned by BCryptHash\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
-
- BCRYPT_KEY_HANDLE pkey = NULL;
-
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptHash\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+ return JNI_FALSE;
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+
+ BCRYPT_KEY_HANDLE pkey = NULL;
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ return JNI_FALSE;
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
- jint sig_len = (*env)->GetArrayLength(env, sig);
- jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
- NTSTATUS result = BCryptVerifySignature(pkey, NULL, hash, hash_len, sig_data, sig_len, 0);
- (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
+ jint sig_len = (*env)->GetArrayLength(env, sig);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ NTSTATUS result = BCryptVerifySignature(pkey, NULL, hash, hash_len, sig_data, sig_len, 0);
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
free(hash);
- BCryptDestroyKey(pkey);
- BCryptCloseAlgorithmProvider(hashHandle, 0);
- BCryptCloseAlgorithmProvider(sigHandle, 0);
-
- if (result == STATUS_SUCCESS) {
- return JNI_TRUE;
- } else if (result == STATUS_INVALID_SIGNATURE) {
- return JNI_FALSE;
- } else {
- wprintf(L"**** Error 0x%x returned by BCryptVerifySignature\n", status);
- return JNI_FALSE;
- }
+ BCryptDestroyKey(pkey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+
+ if (result == STATUS_SUCCESS) {
+ return JNI_TRUE;
+ } else if (result == STATUS_INVALID_SIGNATURE) {
+ return JNI_FALSE;
+ } else {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptVerifySignature\n", status);
+ return JNI_FALSE;
+ }
}
\ No newline at end of file
--
cgit v1.3.1
From 4399ba5e724763675ddda41a9f9380fa565f5584 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sat, 28 Jul 2018 12:39:25 +0200
Subject: Add Simple and Extended native KeyAgreement and Signature SPIs.
---
.../standalone/libs/jni/NativeKeyAgreementSpi.java | 65 ++++++++++++---------
.../standalone/libs/jni/NativeSignatureSpi.java | 68 ++++++++++++----------
2 files changed, 75 insertions(+), 58 deletions(-)
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index 1211519..31886cf 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -16,9 +16,9 @@ import java.security.spec.ECParameterSpec;
* @author Jan Jancar johny@neuromancer.sk
*/
public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
- private ECPrivateKey privateKey;
- private ECPublicKey publicKey;
- private ECParameterSpec params;
+ ECPrivateKey privateKey;
+ ECPublicKey publicKey;
+ ECParameterSpec params;
@Override
protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
@@ -59,23 +59,6 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
return null;
}
- @Override
- protected byte[] engineGenerateSecret() throws IllegalStateException {
- byte[] pubkey;
- if (publicKey instanceof NativeECPublicKey) {
- pubkey = ((NativeECPublicKey) publicKey).getData();
- } else {
- pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), params.getCurve());
- }
- byte[] privkey;
- if (privateKey instanceof NativeECPrivateKey) {
- privkey = ((NativeECPrivateKey) privateKey).getData();
- } else {
- privkey = ECUtil.toByteArray(privateKey.getS(), params.getCurve().getField().getFieldSize());
- }
- return generateSecret(pubkey, privkey, params);
- }
-
@Override
protected int engineGenerateSecret(byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException {
byte[] secret = engineGenerateSecret();
@@ -92,16 +75,46 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
return new SecretKeySpec(engineGenerateSecret(), algorithm);
}
- abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+ private abstract static class SimpleKeyAgreementSpi extends NativeKeyAgreementSpi {
+
+ @Override
+ protected byte[] engineGenerateSecret() throws IllegalStateException {
+ byte[] pubkey;
+ if (publicKey instanceof NativeECPublicKey) {
+ pubkey = ((NativeECPublicKey) publicKey).getData();
+ } else {
+ pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), params.getCurve());
+ }
+ byte[] privkey;
+ if (privateKey instanceof NativeECPrivateKey) {
+ privkey = ((NativeECPrivateKey) privateKey).getData();
+ } else {
+ privkey = ECUtil.toByteArray(privateKey.getS(), params.getCurve().getField().getFieldSize());
+ }
+ return generateSecret(pubkey, privkey, params);
+ }
+
+ abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+ }
+
+ private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi {
+
+ @Override
+ protected byte[] engineGenerateSecret() throws IllegalStateException {
+ return generateSecret(publicKey, privateKey, params);
+ }
+
+ abstract byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, ECParameterSpec params);
+ }
- public static class TomCrypt extends NativeKeyAgreementSpi {
+ public static class TomCrypt extends SimpleKeyAgreementSpi {
@Override
native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
}
- public abstract static class Botan extends NativeKeyAgreementSpi {
+ public abstract static class Botan extends SimpleKeyAgreementSpi {
private String type;
public Botan(String type) {
@@ -148,7 +161,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
- public abstract static class Cryptopp extends NativeKeyAgreementSpi {
+ public abstract static class Cryptopp extends SimpleKeyAgreementSpi {
private String type;
public Cryptopp(String type) {
@@ -165,7 +178,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
- public abstract static class Openssl extends NativeKeyAgreementSpi {
+ public abstract static class Openssl extends SimpleKeyAgreementSpi {
private String type;
public Openssl(String type) {
@@ -182,7 +195,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
- public abstract static class Mscng extends NativeKeyAgreementSpi {
+ public abstract static class Mscng extends SimpleKeyAgreementSpi {
private String type;
public Mscng(String type) {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
index e347120..81c7948 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
@@ -12,11 +12,11 @@ import java.security.spec.ECParameterSpec;
* @author Jan Jancar johny@neuromancer.sk
*/
public abstract class NativeSignatureSpi extends SignatureSpi {
- private ECPublicKey verifyKey;
- private ECPrivateKey signKey;
- private ECParameterSpec params;
+ ECPublicKey verifyKey;
+ ECPrivateKey signKey;
+ ECParameterSpec params;
- private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@Override
protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
@@ -50,27 +50,6 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
buffer.write(b, off, len);
}
- @Override
- protected byte[] engineSign() throws SignatureException {
- byte[] privkey;
- if (signKey instanceof NativeECPrivateKey) {
- privkey = ((NativeECPrivateKey) signKey).getData();
- } else {
- privkey = ECUtil.toByteArray(signKey.getS(), params.getCurve().getField().getFieldSize());
- }
- return sign(buffer.toByteArray(), privkey, params);
- }
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- byte[] pubkey;
- if (verifyKey instanceof NativeECPublicKey) {
- pubkey = ((NativeECPublicKey) verifyKey).getData();
- } else {
- pubkey = ECUtil.toX962Uncompressed(verifyKey.getW(), params);
- }
- return verify(sigBytes, buffer.toByteArray(), pubkey, params);
- }
@Override
@Deprecated
@@ -84,11 +63,36 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
throw new UnsupportedOperationException("getParameter() not supported");
}
- abstract byte[] sign(byte[] data, byte[] privkey, ECParameterSpec params);
+ private abstract static class SimpleSignatureSpi extends NativeSignatureSpi {
- abstract boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params);
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ byte[] privkey;
+ if (signKey instanceof NativeECPrivateKey) {
+ privkey = ((NativeECPrivateKey) signKey).getData();
+ } else {
+ privkey = ECUtil.toByteArray(signKey.getS(), params.getCurve().getField().getFieldSize());
+ }
+ return sign(buffer.toByteArray(), privkey, params);
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ byte[] pubkey;
+ if (verifyKey instanceof NativeECPublicKey) {
+ pubkey = ((NativeECPublicKey) verifyKey).getData();
+ } else {
+ pubkey = ECUtil.toX962Uncompressed(verifyKey.getW(), params);
+ }
+ return verify(sigBytes, buffer.toByteArray(), pubkey, params);
+ }
+
+ abstract byte[] sign(byte[] data, byte[] privkey, ECParameterSpec params);
+
+ abstract boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params);
+ }
- public static class TomCryptRaw extends NativeSignatureSpi {
+ public static class TomCryptRaw extends SimpleSignatureSpi {
@Override
native byte[] sign(byte[] data, byte[] privkey, ECParameterSpec params);
@@ -97,7 +101,7 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
native boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params);
}
- public abstract static class Botan extends NativeSignatureSpi {
+ public abstract static class Botan extends SimpleSignatureSpi {
private String type;
public Botan(String type) {
@@ -237,7 +241,7 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
- public abstract static class Cryptopp extends NativeSignatureSpi {
+ public abstract static class Cryptopp extends SimpleSignatureSpi {
private String type;
public Cryptopp(String type) {
@@ -286,7 +290,7 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
- public abstract static class Openssl extends NativeSignatureSpi {
+ public abstract static class Openssl extends SimpleSignatureSpi {
private String type;
public Openssl(String type) {
@@ -307,7 +311,7 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
- public abstract static class Mscng extends NativeSignatureSpi {
+ public abstract static class Mscng extends SimpleSignatureSpi {
private String type;
public Mscng(String type) {
--
cgit v1.3.1
From f7cd2f14fec676fedc6484eff9a64ebc41d3d910 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sat, 28 Jul 2018 18:34:09 +0200
Subject: Redo Mscng key storage.
---
.../ectester/standalone/ECTesterStandalone.java | 1 -
.../standalone/libs/jni/NativeECPrivateKey.java | 19 +-
.../standalone/libs/jni/NativeECPublicKey.java | 19 +-
.../standalone/libs/jni/NativeSignatureSpi.java | 23 +-
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 315 ++++++++++++++++++---
src/cz/crcs/ectester/standalone/libs/jni/native.h | 38 +--
6 files changed, 345 insertions(+), 70 deletions(-)
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 2897d20..2f132fa 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -275,7 +275,6 @@ public class ECTesterStandalone {
.findFirst()
.orElse(null)));
-
if (kaIdent == null || kpIdent == null) {
throw new NoSuchAlgorithmException(algo);
} else {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
index 76786fe..4cd4a9d 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -86,23 +86,38 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
}
public static class Mscng extends Raw {
+ // 0 -> implicit (meta = curveName UTF16, header = full);
+ // 1 -> explicit (meta = null, header = full);
+ // 2 -> nist (meta = null, header = full)
+ private int flag;
+ private byte[] meta = null;
private byte[] header;
private byte[] x;
private byte[] y;
- public Mscng(byte[] header, byte[] x, byte[] y, byte[] keyData, ECParameterSpec params) {
+ public Mscng(int flag, byte[] meta, byte[] header, byte[] x, byte[] y, byte[] keyData, ECParameterSpec params) {
super(keyData, params);
+ this.flag = flag;
+ this.meta = Arrays.clone(meta);
this.header = Arrays.clone(header);
this.x = Arrays.clone(x);
this.y = Arrays.clone(y);
}
+ public int getFlag() {
+ return flag;
+ }
+
+ public byte[] getMeta() {
+ return Arrays.clone(meta);
+ }
+
public byte[] getHeader() {
return Arrays.clone(header);
}
public byte[] getBlob() {
- return ByteUtil.concatenate(header, x, y, keyData);
+ return ByteUtil.concatenate(header, x, y, keyData);
}
@Override
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
index e55ed33..ccf21c0 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -88,23 +88,38 @@ public abstract class NativeECPublicKey implements ECPublicKey {
}
public static class Mscng extends ANSIX962 {
+ // 0 -> implicit (meta = curveName UTF16, header = full);
+ // 1 -> explicit (meta = null, header = full);
+ // 2 -> nist (meta = null, header = full)
+ private int flag;
+ private byte[] meta = null;
private byte[] header;
private byte[] x;
private byte[] y;
- public Mscng(byte[] header, byte[] x, byte[] y, ECParameterSpec params) {
+ public Mscng(int flag, byte[] meta, byte[] header, byte[] x, byte[] y, ECParameterSpec params) {
super(ByteUtil.concatenate(new byte[]{0x04}, x, y), params);
+ this.flag = flag;
+ this.meta = Arrays.clone(meta);
this.header = Arrays.clone(header);
this.x = Arrays.clone(x);
this.y = Arrays.clone(y);
}
+ public int getFlag() {
+ return flag;
+ }
+
+ public byte[] getMeta() {
+ return Arrays.clone(meta);
+ }
+
public byte[] getHeader() {
return Arrays.clone(header);
}
public byte[] getBlob() {
- return ByteUtil.concatenate(header, x, y);
+ return ByteUtil.concatenate(header, x, y);
}
@Override
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
index 81c7948..b60f2c6 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
@@ -92,6 +92,23 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
abstract boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params);
}
+ private abstract static class ExtendedSignatureSpi extends NativeSignatureSpi {
+
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ return sign(buffer.toByteArray(), signKey, params);
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ return verify(sigBytes, buffer.toByteArray(), verifyKey, params);
+ }
+
+ abstract byte[] sign(byte[] data, ECPrivateKey privkey, ECParameterSpec params);
+
+ abstract boolean verify(byte[] signature, byte[] data, ECPublicKey pubkey, ECParameterSpec params);
+ }
+
public static class TomCryptRaw extends SimpleSignatureSpi {
@Override
@@ -311,7 +328,7 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
- public abstract static class Mscng extends SimpleSignatureSpi {
+ public abstract static class Mscng extends ExtendedSignatureSpi {
private String type;
public Mscng(String type) {
@@ -319,10 +336,10 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
@Override
- native byte[] sign(byte[] data, byte[] privkey, ECParameterSpec params);
+ native byte[] sign(byte[] data, ECPrivateKey privkey, ECParameterSpec params);
@Override
- native boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params);
+ native boolean verify(byte[] signature, byte[] data, ECPublicKey pubkey, ECParameterSpec params);
}
public static class MscngECDSAwithSHA1 extends Mscng {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 12cc13d..8cd96fc 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -6,8 +6,9 @@
#include
-static jclass provider_class;
+
+// BCRYPT and NT things.
#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
#define NT_FAILURE(status) !NT_SUCCESS(status)
@@ -24,6 +25,13 @@ typedef struct {
ULONG cbSeed; //Byte length of the seed used to generate the curve.
} BCRYPT_ECC_PARAMETER_HEADER;
+//Provider things
+static jclass provider_class;
+
+#define KEYFLAG_IMPLICIT 0
+#define KEYFLAG_EXPLICIT 1
+#define KEYFLAG_NIST 2
+
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self) {
jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
provider_class = (*env)->NewGlobalRef(env, local_provider_class);
@@ -138,8 +146,8 @@ static ULONG utf_8to16(NWPSTR *out_buf, LPCSTR in_str) {
return MultiByteToWideChar(CP_UTF8, 0, in_str, -1, *out_buf, result);
}
-// Convert Java String to UTF-16 LPCWSTR null-terminated.
-// Returns: Length of LPCWSTR in bytes!
+// Convert Java String to UTF-16 NWPSTR null-terminated.
+// Returns: Length of NWPSTR in bytes!
static ULONG utf_strto16(NWPSTR *out_buf, JNIEnv *env, jobject str) {
jsize len = (*env)->GetStringLength(env, str);
*out_buf = calloc(len * sizeof(jchar) + 1, 1);
@@ -378,7 +386,7 @@ static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
return bufSize;
}
-static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
+static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, jint *keyflag, NWPSTR *curve_name, LPCWSTR algo, jobject params) {
NTSTATUS status;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
@@ -392,15 +400,14 @@ static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, job
PUCHAR chars = calloc(utf_length + 1, 1);
(*env)->GetStringUTFRegion(env, name, 0, utf_length, chars);
const named_curve_t *curve = lookup_curve(chars);
- NWPSTR curve_utf16;
- ULONG ret = utf_8to16(&curve_utf16, chars);
- if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR)curve_utf16, ret * sizeof(WCHAR), 0))) {
+ ULONG ret = utf_8to16(curve_name, chars);
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR)*curve_name, ret * sizeof(WCHAR), 0))) {
wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
return 0;
}
free(chars);
- free(curve_utf16);
result = curve->bits;
+ *keyflag = KEYFLAG_IMPLICIT;
} else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
PBYTE curve;
ULONG curveLen = create_curve(env, params, &curve);
@@ -419,11 +426,13 @@ static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, job
jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
jint bits = (*env)->CallIntMethod(env, field, get_bits);
result = bits;
+ *keyflag = KEYFLAG_EXPLICIT;
+ *curve_name = NULL;
}
return result;
}
-static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
+static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jint flag, LPCWSTR curve) {
NTSTATUS status;
ULONG bufSize = 0;
if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
@@ -438,6 +447,7 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
PBYTE fullBuf = calloc(bufSize, 1);
if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, fullBuf, bufSize, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, whole)\n", status);
+ free(fullBuf);
return NULL;
}
@@ -462,10 +472,59 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
PBYTE priv_y = priv_x + privHeader->cbFieldLength;
PBYTE priv = priv_y + privHeader->cbFieldLength;
- jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, privHeader, paramLength);
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+
+ jbyteArray meta_bytes = NULL;
+ jbyteArray header_bytes = NULL;
+ switch (flag) {
+ case 0: {
+ // meta = curve
+ jint meta_len = (wcslen(curve) + 1) * sizeof(WCHAR);
+ meta_bytes = (*env)->NewByteArray(env, meta_len);
+ jbyte *meta_data = (*env)->GetByteArrayElements(env, meta_bytes, NULL);
+ memcpy(meta_data, curve, meta_len);
+ (*env)->ReleaseByteArrayElements(env, meta_bytes, meta_data, 0);
+ }
+ case 1:
+ case 2: {
+ // meta = null
+ // header = full
+ header_bytes = (*env)->NewByteArray(env, paramLength);
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, fullBuf, paramLength);
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ break;
+ }
+ default:
+ // header = small
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, length only)\n", status);
+ free(fullBuf);
+ return NULL;
+ }
+ if (bufSize == 0) {
+ printf("buf 0\n");
+ free(fullBuf);
+ return NULL;
+ }
+ PBYTE smallBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, smallBuf, bufSize, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, whole)\n", status);
+ free(fullBuf);
+ free(smallBuf);
+ return NULL;
+ }
+ // smallBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // Qx[cbFieldLength] X-coordinate of the public point.
+ // Qy[cbFieldLength] Y-coordinate of the public point.
+ // d[cbSubgroupOrder] Private key.
+ header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, smallBuf, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ free(smallBuf);
+ break;
+ }
jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
@@ -484,11 +543,11 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
free(fullBuf);
- jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "([B[B[B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "", "(I[B[B[B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, privkey_class, ec_priv_init, flag, meta_bytes, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
}
-static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
+static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jint flag, LPCWSTR curve) {
NTSTATUS status;
ULONG bufSize = 0;
if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
@@ -525,10 +584,55 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
PBYTE pub_x = &fullBuf[paramLength];
PBYTE pub_y = pub_x + pubHeader->cbFieldLength;
- jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, pubHeader, paramLength);
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ jbyteArray meta_bytes = NULL;
+ jbyteArray header_bytes = NULL;
+ switch (flag) {
+ case 0: {
+ // meta = curve
+ jint meta_len = (wcslen(curve) + 1) * sizeof(WCHAR);
+ meta_bytes = (*env)->NewByteArray(env, meta_len);
+ jbyte *meta_data = (*env)->GetByteArrayElements(env, meta_bytes, NULL);
+ memcpy(meta_data, curve, meta_len);
+ (*env)->ReleaseByteArrayElements(env, meta_bytes, meta_data, 0);
+ }
+ case 1:
+ case 2: {
+ header_bytes = (*env)->NewByteArray(env, paramLength);
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, pubHeader, paramLength);
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ break;
+ }
+ default:
+ // header = small
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, length only)\n", status);
+ free(fullBuf);
+ return NULL;
+ }
+ if (bufSize == 0) {
+ printf("buf 0\n");
+ free(fullBuf);
+ return NULL;
+ }
+ PBYTE smallBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, smallBuf, bufSize, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, whole)\n", status);
+ free(fullBuf);
+ free(smallBuf);
+ return NULL;
+ }
+ // smallBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // Qx[cbFieldLength] X-coordinate of the public point.
+ // Qy[cbFieldLength] Y-coordinate of the public point.
+ header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, smallBuf, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ free(smallBuf);
+ break;
+ }
jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
@@ -542,8 +646,8 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
free(fullBuf);
- jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "", "(I[B[B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, pubkey_class, ec_pub_init, flag, meta_bytes, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
}
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
@@ -610,8 +714,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return NULL;
}
- jobject privkey = key_to_privkey(env, key);
- jobject pubkey = key_to_pubkey(env, key);
+ jobject privkey = key_to_privkey(env, key, KEYFLAG_NIST, NULL);
+ jobject pubkey = key_to_pubkey(env, key, KEYFLAG_NIST, NULL);
jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
@@ -640,7 +744,9 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
}
(*env)->ReleaseStringUTFChars(env, type, type_data);
- ULONG bits = init_algo(env, &handle, algo, params);
+ jint keyflag;
+ NWPSTR curveName;
+ ULONG bits = init_algo(env, &handle, &keyflag, &curveName, algo, params);
if (bits == 0) {
throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
return NULL;
@@ -658,8 +764,12 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return NULL;
}
- jobject privkey = key_to_privkey(env, key);
- jobject pubkey = key_to_pubkey(env, key);
+ jobject privkey = key_to_privkey(env, key, keyflag, curveName);
+ jobject pubkey = key_to_pubkey(env, key, keyflag, curveName);
+
+ if (curveName) {
+ free(curveName);
+ }
jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
@@ -668,9 +778,109 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
+static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR type, jint keyflag, jbyteArray meta, jobject params) {
+ LPCWSTR ecdh_algos[] = {
+ BCRYPT_ECDH_ALGORITHM,
+ BCRYPT_ECDH_P256_ALGORITHM,
+ BCRYPT_ECDH_P384_ALGORITHM,
+ BCRYPT_ECDH_P521_ALGORITHM
+ };
+ LPCWSTR ecdsa_algos[] = {
+ BCRYPT_ECDSA_ALGORITHM,
+ BCRYPT_ECDSA_P256_ALGORITHM,
+ BCRYPT_ECDSA_P384_ALGORITHM,
+ BCRYPT_ECDSA_P521_ALGORITHM
+ };
+
+ LPCWSTR *algos;
+ LPCWSTR algo;
+ if (lstrcmpW(type, BCRYPT_ECDH_ALGORITHM) == 0) {
+ algos = ecdh_algos;
+ } else if (lstrcmpW(type, BCRYPT_ECDSA_ALGORITHM) == 0) {
+ algos = ecdsa_algos;
+ } else {
+ //unreachable
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (keyflag) {
+ case 0:
+ case 1:
+ algo = algos[0];
+ break;
+ case 2: {
+ 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);
+ switch (bits) {
+ case 256:
+ algo = algos[1];
+ break;
+ case 384:
+ algo = algos[2];
+ break;
+ case 521:
+ algo = algos[3];
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+ break;
+ }
+ }
+ NTSTATUS status;
+
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return status;
+ }
+
+ switch (keyflag) {
+ case 0: {
+ jint meta_len = (*env)->GetArrayLength(env, meta);
+ jbyte *meta_data = (*env)->GetByteArrayElements(env, meta, NULL);
+ //if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, meta_data, meta_len, 0))) {
+ // throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSetProperty(curve name)\n", status);
+ // (*env)->ReleaseByteArrayElements(env, meta, meta_data, JNI_ABORT);
+ // return status;
+ //}
+ (*env)->ReleaseByteArrayElements(env, meta, meta_data, JNI_ABORT);
+ break;
+ }
+ case 1: {
+ PBYTE curve;
+ ULONG curve_len = create_curve(env, params, &curve);
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curve_len, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSetProperty(parameters)\n", status);
+ free(curve);
+ return status;
+ }
+ free(curve);
+ break;
+ }
+ }
+ return STATUS_SUCCESS;
+}
+
+static jint get_keyflag(JNIEnv *env, jobject key) {
+ jclass key_class = (*env)->GetObjectClass(env, key);
+ jmethodID get_flag = (*env)->GetMethodID(env, key_class, "getFlag", "()I");
+ return (*env)->CallIntMethod(env, key, get_flag);
+}
+
+static jbyteArray get_meta(JNIEnv *env, jobject key) {
+ jclass key_class = (*env)->GetObjectClass(env, key);
+ jmethodID get_meta = (*env)->GetMethodID(env, key_class, "getMeta", "()[B");
+ return (jbyteArray)(*env)->CallObjectMethod(env, key, get_meta);
+}
+
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
NTSTATUS status;
- printf("generateSecret!\n");
jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
@@ -693,9 +903,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
BCRYPT_ALG_HANDLE kaHandle = NULL;
- ULONG bits = init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params);
- if (bits == 0) {
- throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
+ jint pub_flag = get_keyflag(env, pubkey);
+ jbyteArray meta = get_meta(env, pubkey);
+
+ if (NT_FAILURE(status = init_use_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, pub_flag, meta, params))) {
return NULL;
}
@@ -712,6 +923,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
}
(*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ jint priv_flag = get_keyflag(env, privkey);
jint priv_length = (*env)->GetArrayLength(env, privkey);
jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
@@ -791,12 +1003,19 @@ static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) {
return hash_algo;
}
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jobject privkey, jobject params) {
NTSTATUS status;
LPCWSTR hash_algo = get_sighash_algo(env, self);
BCRYPT_ALG_HANDLE sigHandle = NULL;
+ jint keyflag = get_keyflag(env, privkey);
+ jbyteArray meta = get_meta(env, privkey);
+
+ if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
+ return NULL;
+ }
+
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
return NULL;
@@ -835,17 +1054,21 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
BCRYPT_KEY_HANDLE skey = NULL;
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ jmethodID get_data = (*env)->GetMethodID(env, privkey_class, "getData", "()[B");
+ jbyteArray privkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, privkey, get_data);
+
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey_barray);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey_barray, NULL);
if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair\n", status);
BCryptCloseAlgorithmProvider(sigHandle, 0);
BCryptCloseAlgorithmProvider(hashHandle, 0);
free(hash);
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, privkey_barray, priv_data, JNI_ABORT);
return NULL;
}
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, privkey_barray, priv_data, JNI_ABORT);
DWORD sig_len = 0;
if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
@@ -877,14 +1100,16 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
return sig;
}
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) {
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jobject pubkey, jobject params) {
NTSTATUS status;
LPCWSTR hash_algo = get_sighash_algo(env, self);
BCRYPT_ALG_HANDLE sigHandle = NULL;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ jint keyflag = get_keyflag(env, pubkey);
+ jbyteArray meta = get_meta(env, pubkey);
+
+ if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
return JNI_FALSE;
}
@@ -921,17 +1146,21 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
BCRYPT_KEY_HANDLE pkey = NULL;
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ jmethodID get_data = (*env)->GetMethodID(env, pubkey_class, "getData", "()[B");
+ jbyteArray pubkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, pubkey, get_data);
+
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey_barray);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey_barray, NULL);
if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair\n", status);
BCryptCloseAlgorithmProvider(sigHandle, 0);
BCryptCloseAlgorithmProvider(hashHandle, 0);
free(hash);
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
return JNI_FALSE;
}
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
jint sig_len = (*env)->GetArrayLength(env, sig);
jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index a2dedae..e8dff88 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -35,7 +35,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_getC
extern "C" {
#endif
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE 2147483639L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS
@@ -45,9 +45,9 @@ extern "C" {
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES 2L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739i64
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt
* Method: setup
@@ -206,7 +206,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurv
extern "C" {
#endif
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 1421746759512286392LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 1421746759512286392i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE 2147483639L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_KEYS
@@ -216,9 +216,9 @@ extern "C" {
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES 2L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 4112578634029874840LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 4112578634029874840i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -4298000515446427739LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -4298000515446427739i64
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan
* Method: setup
@@ -377,7 +377,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getC
extern "C" {
#endif
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 1421746759512286392LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 1421746759512286392i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE 2147483639L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_KEYS
@@ -387,9 +387,9 @@ extern "C" {
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES 2L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 4112578634029874840LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 4112578634029874840i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -4298000515446427739LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -4298000515446427739i64
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp
* Method: setup
@@ -548,7 +548,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCu
extern "C" {
#endif
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392i64
#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
@@ -558,9 +558,9 @@ extern "C" {
#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
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 4112578634029874840i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739i64
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl
* Method: setup
@@ -719,7 +719,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurv
extern "C" {
#endif
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 1421746759512286392LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 1421746759512286392i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE 2147483639L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS
@@ -729,9 +729,9 @@ extern "C" {
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES
#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES 2L
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 4112578634029874840LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 4112578634029874840i64
#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -4298000515446427739LL
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -4298000515446427739i64
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
* Method: setup
@@ -838,18 +838,18 @@ extern "C" {
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
* Method: sign
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ * Signature: ([BLjava/security/interfaces/ECPrivateKey;Ljava/security/spec/ECParameterSpec;)[B
*/
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+ (JNIEnv *, jobject, jbyteArray, jobject, jobject);
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
* Method: verify
- * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ * Signature: ([B[BLjava/security/interfaces/ECPublicKey;Ljava/security/spec/ECParameterSpec;)Z
*/
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jobject);
#ifdef __cplusplus
}
--
cgit v1.3.1
From 25cb7f41a871b890a194ff4ccdf6230c4bc22a99 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sun, 29 Jul 2018 14:00:55 +0200
Subject: Try to fix ECDH with KDF loading.
---
.../ectester/standalone/libs/jni/NativeKeyAgreementSpi.java | 12 ++++++++++++
src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java | 10 +++++++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index 31886cf..aa053bf 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -20,6 +20,10 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
ECPublicKey publicKey;
ECParameterSpec params;
+ public NativeKeyAgreementSpi() {
+
+ }
+
@Override
protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
if (!(key instanceof ECPrivateKey)) {
@@ -77,6 +81,10 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
private abstract static class SimpleKeyAgreementSpi extends NativeKeyAgreementSpi {
+ public SimpleKeyAgreementSpi() {
+
+ }
+
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
byte[] pubkey;
@@ -99,6 +107,10 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi {
+ public ExtendedKeyAgreementSpi() {
+
+ }
+
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
return generateSecret(publicKey, privateKey, params);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
index f580d74..fef2930 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
@@ -12,10 +12,14 @@ public abstract class NativeProvider extends Provider {
public NativeProvider(String name, double version, String info) {
super(name, version, info);
- AccessController.doPrivileged((PrivilegedAction
+
+
+
+
+
+
+
+
diff --git a/nbproject/keystore b/nbproject/keystore
new file mode 100755
index 0000000..7c9c8e4
Binary files /dev/null and b/nbproject/keystore differ
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
index e337e70..3530fe9 100755
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
@@ -9,7 +9,7 @@ setlocal EnableDelayedExpansion
:: See if we are cleaning.
if "%1" == "clean" (
echo ** cleaning
- del mscng_provider.dll
+ del *.dll *.exp *.lib *.obj
exit
)
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index aa053bf..c11c803 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -20,10 +20,6 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
ECPublicKey publicKey;
ECParameterSpec params;
- public NativeKeyAgreementSpi() {
-
- }
-
@Override
protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
if (!(key instanceof ECPrivateKey)) {
@@ -81,10 +77,6 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
private abstract static class SimpleKeyAgreementSpi extends NativeKeyAgreementSpi {
- public SimpleKeyAgreementSpi() {
-
- }
-
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
byte[] pubkey;
@@ -107,10 +99,6 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi {
- public ExtendedKeyAgreementSpi() {
-
- }
-
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
return generateSecret(publicKey, privateKey, params);
@@ -207,7 +195,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
- public abstract static class Mscng extends SimpleKeyAgreementSpi {
+ public abstract static class Mscng extends ExtendedKeyAgreementSpi {
private String type;
public Mscng(String type) {
@@ -215,7 +203,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
@Override
- native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+ native byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, ECParameterSpec params);
}
public static class MscngECDHwithSHA1KDF extends Mscng {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 8cd96fc..a284901 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -125,15 +125,6 @@ static const named_curve_t* lookup_curve(const char *name) {
return NULL;
}
-static const named_curve_t* lookup_curve_bits(jint bitsize) {
- for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
- if (bitsize == named_curves[i].bits) {
- return &named_curves[i];
- }
- }
- return NULL;
-}
-
static ULONG utf_16to8(NPSTR *out_buf, LPCWSTR in_str) {
INT result = WideCharToMultiByte(CP_UTF8, 0, in_str, -1, NULL, 0, NULL, NULL);
*out_buf = calloc(result, 1);
@@ -146,8 +137,10 @@ static ULONG utf_8to16(NWPSTR *out_buf, LPCSTR in_str) {
return MultiByteToWideChar(CP_UTF8, 0, in_str, -1, *out_buf, result);
}
-// Convert Java String to UTF-16 NWPSTR null-terminated.
-// Returns: Length of NWPSTR in bytes!
+/**
+ * Convert Java String to UTF-16 NWPSTR null-terminated.
+ * Returns: Length of NWPSTR in bytes!
+ */
static ULONG utf_strto16(NWPSTR *out_buf, JNIEnv *env, jobject str) {
jsize len = (*env)->GetStringLength(env, str);
*out_buf = calloc(len * sizeof(jchar) + 1, 1);
@@ -333,7 +326,7 @@ static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
jint bits = (*env)->CallIntMethod(env, field, get_bits);
jint bytes = (bits + 7) / 8;
- jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getA", "()Ljava/math/BigInteger;");
jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
@@ -879,7 +872,7 @@ static jbyteArray get_meta(JNIEnv *env, jobject key) {
return (jbyteArray)(*env)->CallObjectMethod(env, key, get_meta);
}
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jobject pubkey, jobject privkey, jobject params) {
NTSTATUS status;
jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
@@ -973,7 +966,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
(*env)->ReleaseByteArrayElements(env, result, result_data, 0);
free(derived);
-
BCryptDestroyKey(pkey);
BCryptDestroyKey(skey);
BCryptDestroySecret(ka);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index e8dff88..b5cde43 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -1,857 +1,857 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include
-/* Header for class cz_crcs_ectester_standalone_libs_TomcryptLib */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_TomcryptLib
-#define _Included_cz_crcs_ectester_standalone_libs_TomcryptLib
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_TomcryptLib
- * Method: createProvider
- * Signature: ()Ljava/security/Provider;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_createProvider
- (JNIEnv *, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_TomcryptLib
- * Method: getCurves
- * Signature: ()Ljava/util/Set;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_getCurves
- (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE 2147483639L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS 0L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES 1L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES 2L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739i64
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt
- * Method: setup
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024TomCrypt_setup
- (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
- * Method: keysizeSupported
- * Signature: (I)Z
- */
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_keysizeSupported
- (JNIEnv *, jobject, jint);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
- * Method: paramsSupported
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
- */
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_paramsSupported
- (JNIEnv *, jobject, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
- * Method: generate
- * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_generate__ILjava_security_SecureRandom_2
- (JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
- * Method: generate
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_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_TomCrypt */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt
- * Method: generateSecret
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
- * Method: sign
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_sign
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
- * Method: verify
- * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
- */
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_verify
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_BotanLib */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_BotanLib
-#define _Included_cz_crcs_ectester_standalone_libs_BotanLib
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject);
-
-/*
- * 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 *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 1421746759512286392i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE 2147483639L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_KEYS
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_KEYS 0L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_VALUES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_VALUES 1L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES 2L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 4112578634029874840i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -4298000515446427739i64
-/*
- * 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 *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject, jint);
-
-/*
- * 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 *, jobject, jobject);
-
-/*
- * 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 *, jobject, jint, jobject);
-
-/*
- * 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 *, jobject, jobject, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Botan */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Botan
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Botan
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Botan */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Botan
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Botan
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject, jbyteArray, jbyteArray, jobject);
-
-/*
- * 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 *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_CryptoppLib */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_CryptoppLib
-#define _Included_cz_crcs_ectester_standalone_libs_CryptoppLib
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject);
-
-/*
- * 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 *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 1421746759512286392i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE 2147483639L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_KEYS
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_KEYS 0L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_VALUES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_VALUES 1L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES 2L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 4112578634029874840i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -4298000515446427739i64
-/*
- * 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 *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject, jint);
-
-/*
- * 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 *, jobject, jobject);
-
-/*
- * 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 *, jobject, jint, jobject);
-
-/*
- * 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 *, jobject, jobject, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Cryptopp */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Cryptopp
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Cryptopp
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Cryptopp */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Cryptopp
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Cryptopp
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * 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 *, jobject, jbyteArray, jbyteArray, jobject);
-
-/*
- * 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 *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#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 1421746759512286392i64
-#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 4112578634029874840i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739i64
-/*
- * 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
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl
- * Method: generateSecret
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Openssl_generateSecret
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
- * Method: sign
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_sign
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
- * Method: verify
- * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
- */
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_verify
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_MscngLib */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_MscngLib
-#define _Included_cz_crcs_ectester_standalone_libs_MscngLib
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_MscngLib
- * Method: createProvider
- * Signature: ()Ljava/security/Provider;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider
- (JNIEnv *, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_MscngLib
- * Method: getCurves
- * Signature: ()Ljava/util/Set;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurves
- (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 1421746759512286392i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE 2147483639L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS 0L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_VALUES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_VALUES 1L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES 2L
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 4112578634029874840i64
-#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
-#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -4298000515446427739i64
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
- * Method: setup
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup
- (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
- * Method: keysizeSupported
- * Signature: (I)Z
- */
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported
- (JNIEnv *, jobject, jint);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
- * Method: paramsSupported
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
- */
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported
- (JNIEnv *, jobject, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
- * Method: generate
- * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2
- (JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
- * Method: generate
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
- */
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_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_Mscng */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Mscng
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Mscng
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
- * Method: generateSecret
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
-#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
- * Method: sign
- * Signature: ([BLjava/security/interfaces/ECPrivateKey;Ljava/security/spec/ECParameterSpec;)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign
- (JNIEnv *, jobject, jbyteArray, jobject, jobject);
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
- * Method: verify
- * Signature: ([B[BLjava/security/interfaces/ECPublicKey;Ljava/security/spec/ECParameterSpec;)Z
- */
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify
- (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class cz_crcs_ectester_standalone_libs_TomcryptLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_TomcryptLib
+#define _Included_cz_crcs_ectester_standalone_libs_TomcryptLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_TomcryptLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_TomcryptLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739i64
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024TomCrypt_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
+ * Method: keysizeSupported
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_keysizeSupported
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
+ * Method: paramsSupported
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_paramsSupported
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_generate__ILjava_security_SecureRandom_2
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_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_TomCrypt */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_BotanLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_BotanLib
+#define _Included_cz_crcs_ectester_standalone_libs_BotanLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject);
+
+/*
+ * 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 *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 1421746759512286392i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 4112578634029874840i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -4298000515446427739i64
+/*
+ * 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 *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject, jint);
+
+/*
+ * 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 *, jobject, jobject);
+
+/*
+ * 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 *, jobject, jint, jobject);
+
+/*
+ * 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 *, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Botan */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Botan
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Botan
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Botan */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Botan
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Botan
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * 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 *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_CryptoppLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_CryptoppLib
+#define _Included_cz_crcs_ectester_standalone_libs_CryptoppLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject);
+
+/*
+ * 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 *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 1421746759512286392i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 4112578634029874840i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -4298000515446427739i64
+/*
+ * 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 *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject, jint);
+
+/*
+ * 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 *, jobject, jobject);
+
+/*
+ * 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 *, jobject, jint, jobject);
+
+/*
+ * 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 *, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Cryptopp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Cryptopp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Cryptopp
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Cryptopp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Cryptopp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Cryptopp
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * 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 *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * 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 *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#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 1421746759512286392i64
+#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 4112578634029874840i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739i64
+/*
+ * 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
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Openssl_generateSecret
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_MscngLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_MscngLib
+#define _Included_cz_crcs_ectester_standalone_libs_MscngLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_MscngLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_MscngLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 1421746759512286392i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 4112578634029874840i64
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -4298000515446427739i64
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: keysizeSupported
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: paramsSupported
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Mscng
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_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_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
+ * Method: generateSecret
+ * Signature: (Ljava/security/interfaces/ECPublicKey;Ljava/security/interfaces/ECPrivateKey;Ljava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret
+ (JNIEnv *, jobject, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+ * Method: sign
+ * Signature: ([BLjava/security/interfaces/ECPrivateKey;Ljava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign
+ (JNIEnv *, jobject, jbyteArray, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng
+ * Method: verify
+ * Signature: ([B[BLjava/security/interfaces/ECPublicKey;Ljava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--
cgit v1.3.1
From 8d21a87b25550215a4c59ff4ef8d32e2f0736b3f Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sun, 29 Jul 2018 14:07:04 +0200
Subject: Update docs on Standalone testing.
---
README.md | 78 ++++++++++++++--------
.../ectester/standalone/ECTesterStandalone.java | 2 +-
2 files changed, 53 insertions(+), 27 deletions(-)
diff --git a/README.md b/README.md
index 7121027..b18ebbd 100644
--- a/README.md
+++ b/README.md
@@ -231,6 +231,11 @@ For more information on ECC libraries see [LIBS](docs/LIBS.md).
### Setup
+OpenJDK JRE is required to test ECDH on Windows properly, as Oracle JRE requires the Java Cryptography Providers
+for certain classes (such as a [KeyAgreement](https://docs.oracle.com/javase/8/docs/api/javax/crypto/KeyAgreement.html))
+to be signed by keys that are signed by their JCA Code Signing Authority. ECTester internally uses Java Cryptography Provider
+API to expose and test native libraries. OpenJDK for Windows can be obtained from [ojdkbuild/ojdkbuild](https://github.com/ojdkbuild/ojdkbuild).
+
Installing the Java Cryptography Extension Unlimited Strength policy files is necessary to do testing
with quite a lot of practical key sizes, they are available for download:
@@ -243,49 +248,70 @@ To install, place them in `${java.home}/jre/lib/security/`.
### Options
```
-usage: ECTesterStandalone.jar [-V] [-h] [ (ecdh [-t ] [-n ] [-b ] [-nc ]) |
-(ecdsa [-t ] [-n ] [-b ] [-nc ] [-f ]) |
-(export [-t ] [-b ]) | (generate [-nc ] [-n ] [-t
-] [-b ]) | (list-data [what]) | (list-libs) | (test [-gt ]
-[-kt ] [-st ] [-b ] [-nc ]) ] [lib]
-
- -V,--version Print version info.
- -h,--help Print help.
- [lib] What library to use.
-
- ecdh:
+usage: ECTesterStandalone.jar [-V] [-h] [-C]
+ [ (ecdh [-b ] [-nc ] [-cn ] [-t ] [--key-type ] [-n ]) |
+ (ecdsa [-b ] [-nc ] [-cn ] [-t ] [-n ] [-f ]) |
+ (export [-b ] [-t ]) |
+ (generate [-b ] [-nc ] [-cn ] [-n ] [-t ]) |
+ (list-data [what]) |
+ (list-libs) |
+ (list-suites) |
+ (test [-b ] [-nc ] [-cn ] [-gt ] [-kt ] [-st ] [-f ] [--key-type ]
+ ) ]
+ [lib]
+
+ ecdh: | Perform EC based KeyAgreement. |
+ -b,--bits What size of curve to use.
+ -nc,--named-curve Use a named curve, from CurveDB:
+ -cn,--curve-name Use a named curve, search from curves
+ supported by the library:
-t,--type Set KeyAgreement object [type].
+ --key-type Set the key [algorithm] for which the key
+ should be derived in KeyAgreements with
+ KDF. Default is "AES".
-n,--amount Do ECDH [amount] times.
+
+ ecdsa: | Perform EC based Signature. |
-b,--bits What size of curve to use.
-nc,--named-curve Use a named curve, from CurveDB:
-
- ecdsa:
+ -cn,--curve-name Use a named curve, search from curves
+ supported by the library:
-t,--type Set Signature object [type].
-n,--amount Do ECDSA [amount] times.
- -b,--bits What size of curve to use.
- -nc,--named-curve Use a named curve, from CurveDB:
-f,--file Input [file] to sign.
- export:
- -t,--type Set KeyPair object [type].
- -b,--bits What size of curve to use.
+ export: | Export default curve parameters. |
+ -b,--bits What size of curve to use.
+ -t,--type Set KeyPair object [type].
- generate:
+ generate: | Generate EC keypairs. |
+ -b,--bits What size of curve to use.
-nc,--named-curve Use a named curve, from CurveDB:
+ -cn,--curve-name Use a named curve, search from curves
+ supported by the library:
-n,--amount Generate [amount] of EC keys.
-t,--type Set KeyPairGenerator object [type].
- -b,--bits What size of curve to use.
- list-data:
- [what] what to list.
+ list-data: | List/show contained EC domain parameters/keys. |
+ [what] what to list.
+
+ list-libs: | List supported libraries. |
- list-libs:
+ list-suites: | List supported test suites. |
- test:
+ test: | Test a library. |
+ -b,--bits What size of curve to use.
+ -nc,--named-curve Use a named curve, from CurveDB:
+ -cn,--curve-name Use a named curve, search from curves
+ supported by the library:
-gt,--kpg-type Set the KeyPairGenerator object [type].
-kt,--ka-type Set the KeyAgreement object [type].
-st,--sig-type Set the Signature object [type].
- -b,--bits What size of curve to use.
- -nc,--named-curve Use a named curve, from CurveDB:
+ -f,--format Set the output format, one of
+ text,yaml,xml.
+ --key-type Set the key [algorithm] for which the key
+ should be derived in KeyAgreements with
+ KDF. Default is "AES".
+ The test suite to run.
```
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 2f132fa..31d291c 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -180,8 +180,8 @@ public class ECTesterStandalone {
actions.put("generate", generate);
Options exportOpts = new Options();
- exportOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPair object [type].").build());
exportOpts.addOption(bits);
+ exportOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPair object [type].").build());
ParserOptions export = new ParserOptions(new DefaultParser(), exportOpts, "Export default curve parameters.");
actions.put("export", export);
--
cgit v1.3.1
From 21ecc7501145b5e9b239dd5a62ccbefdcaa3a160 Mon Sep 17 00:00:00 2001
From: J08nY
Date: Sun, 29 Jul 2018 17:21:04 +0200
Subject: Somewhat finished Mscng implementation.
---
.gitignore | 1 +
README.md | 6 +-
.../crcs/ectester/standalone/libs/jni/Makefile.bat | 46 ++++++++-----
.../standalone/libs/jni/NativeKeyAgreementSpi.java | 42 +++++++-----
src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 78 ++++++++++++++++------
src/cz/crcs/ectester/standalone/libs/jni/native.h | 2 +-
6 files changed, 118 insertions(+), 57 deletions(-)
diff --git a/.gitignore b/.gitignore
index f40221d..8f7585a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@
/src/**/*.dll
/src/**/*.exp
/src/**/*.lib
+/src/**/*.pdb
diff --git a/README.md b/README.md
index b18ebbd..2b331ff 100644
--- a/README.md
+++ b/README.md
@@ -239,9 +239,9 @@ API to expose and test native libraries. OpenJDK for Windows can be obtained fro
Installing the Java Cryptography Extension Unlimited Strength policy files is necessary to do testing
with quite a lot of practical key sizes, they are available for download:
- * [Java 6](http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html)
- * [Java 7](http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html)
- * [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html)
+ - [Java 6](http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html)
+ - [Java 7](http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html)
+ - [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html)
To install, place them in `${java.home}/jre/lib/security/`.
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
index 3530fe9..9b0d6f7 100755
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat
@@ -5,6 +5,7 @@ setlocal EnableDelayedExpansion
:: - JAVA_HOME
:: - CC
:: - USE_EXT_MSCNG
+:: - DEBUG
:: See if we are cleaning.
if "%1" == "clean" (
@@ -13,11 +14,13 @@ if "%1" == "clean" (
exit
)
+set TAB=
+
:: Determine arch.
-reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && (set ARCH=32& set ARCH_S=x86& set ARCH_VS=x86) || (set ARCH=64& set ARCH_S=x64& set ARCH_VS=amd64)
+reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL 2>&1 && (set ARCH=32& set ARCH_S=x86& set ARCH_VS=x86) || (set ARCH=64& set ARCH_S=x64& set ARCH_VS=amd64)
-echo ** ARCH %ARCH_S%
+echo ** ARCH%TAB%%TAB%%ARCH_S%
:: Find a working visual studio environment.
@@ -27,7 +30,7 @@ set vsw_path="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
set vs_path=
for /f "usebackq delims=" %%i in (`%vsw_path% -nologo -prerelease -latest -property installationPath`) do (
if exist "%%i\Common7\Tools\vsdevcmd.bat" (
- echo ** VsDevCmd at %%i\Common7\Tools\vsdevcmd.bat
+ echo ** VsDevCmd%TAB%%TAB%%%i\Common7\Tools\vsdevcmd.bat
call "%%i\Common7\Tools\vsdevcmd.bat" -no_logo -arch=%ARCH_VS%
if ERRORLEVEL 1 (
echo nope.
@@ -45,7 +48,7 @@ if %found% EQU 0 (
exit /b 2
)
-echo ** VS_PATH %vs_path%
+echo ** VS_PATH%TAB%%TAB%%vs_path%
:: Try to find vcruntime.
@@ -55,7 +58,7 @@ if exist %vc_base% (
for /f "delims=" %%i in ('dir /b /on "!vc_base!"') do (
set vc_version=%%i
)
- echo ** VC_VERSION !vc_version!
+ echo ** VC_VERSION%TAB%!vc_version!
set vc_include=%vc_base%!vc_version!\include
set vc_lib=%vc_base%!vc_version!\lib\%ARCH_S%
)
@@ -77,8 +80,8 @@ popd
set mscng_lib_arch=%mscng_lib%\X%ARCH%
-echo ** CNG_INCLUDE !mscng_include!
-echo ** CNG_LIB !mscng_lib!
+echo ** CNG_INCLUDE%TAB%%mscng_include%
+echo ** CNG_LIB%TAB%%TAB%%mscng_lib_arch%
:: Get the paths to Java JNI.
@@ -92,7 +95,7 @@ if not defined JAVA_HOME (
popd
)
-echo ** JAVA_HOME !JAVA_HOME!
+echo ** JAVA_HOME%TAB%%JAVA_HOME%
set JNI_INCLUDEDIR=%JAVA_HOME%\include
set JNI_PLATFORMINCLUDEDIR=%JNI_INCLUDEDIR%\win32
@@ -104,7 +107,7 @@ if not defined CC (
set CC=cl.exe
)
-echo ** CC !CC!
+echo ** CC%TAB%%TAB%%CC%
:: Try to find uCRT.
@@ -114,7 +117,7 @@ if exist %ucrt_base% (
for /f "delims=" %%i in ('dir /b /on "!ucrt_base!\Include"') do (
set ucrt_version=%%i
)
- echo ** uCRT !ucrt_version!
+ echo ** uCRT%TAB%%TAB%!ucrt_version!
set ucrt_include=%ucrt_base%Include\!ucrt_version!\ucrt
set ucrt_lib=%ucrt_base%Lib\!ucrt_version!
set ucrt_lib_arch=!ucrt_lib!\ucrt\%ARCH_S%
@@ -128,8 +131,8 @@ if defined USE_EXT_MSCNG (
set INCLUDE_CLI=!INCLUDE_CLI! /I"%mscng_include%"
)
-echo ** INCLUDE %INCLUDE%
-echo ** INCLUDE_CLI %INCLUDE_CLI%
+echo ** INCLUDE%TAB%%TAB%%INCLUDE%
+echo ** INCLUDE_CLI%TAB%%INCLUDE_CLI%
:: Setup LIB paths.
@@ -139,9 +142,22 @@ if defined USE_EXT_MSCNG (
set LIBPATH=!LIBPATH! /LIBPATH:"%mscng_lib_arch%"
)
-echo ** LIB %LIB%
-echo ** LIBPATH %LIBPATH%
+echo ** LIB%TAB%%TAB%%LIB%
+echo ** LIBPATH%TAB%%TAB%%LIBPATH%
+
+
+:: Setup DEBUB options.
+set OTHER_CLI=
+if defined DEBUG (
+ set OTHER_CLI=/Od /Z7
+) else (
+ set OTHER_CLI=/O2
+)
+
+echo ** OTHER_CLI%TAB%%OTHER_CLI%
echo.
+echo ^>^> %CC% /W2 /EHsc %OTHER_CLI% %INCLUDE_CLI% mscng.c c_utils.c bcrypt.lib jvm.lib /Femscng_provider.dll /LD /link %LIBPATH% /nologo
+echo.
-%CC% /EHsc %INCLUDE_CLI% mscng.c c_utils.c bcrypt.lib jvm.lib /Femscng_provider.dll /LD /link %LIBPATH%
\ No newline at end of file
+%CC% /W2 /EHsc %OTHER_CLI% %INCLUDE_CLI% mscng.c c_utils.c bcrypt.lib jvm.lib /Femscng_provider.dll /LD /link %LIBPATH% /nologo
\ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index c11c803..4ed3469 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -11,6 +11,7 @@ import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECParameterSpec;
+import java.security.spec.ECGenParameterSpec;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -18,7 +19,7 @@ import java.security.spec.ECParameterSpec;
public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
ECPrivateKey privateKey;
ECPublicKey publicKey;
- ECParameterSpec params;
+ AlgorithmParameterSpec params;
@Override
protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
@@ -30,15 +31,6 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
this.params = privateKey.getParams();
}
- @Override
- protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- if (!(params instanceof ECParameterSpec)) {
- throw new InvalidAlgorithmParameterException();
- }
- engineInit(key, random);
- this.params = (ECParameterSpec) params;
- }
-
@Override
protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException {
if (privateKey == null) {
@@ -71,27 +63,36 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
@Override
protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException {
- // TODO: This is dangerous/not correct ! Need to actually implement KDF1 and KDF2 here probably.
+ // TODO: This is dangerous/not correct ! Need to actually implement KDF1 and KDF2 here probably. Or just pass it off to the libs through some different interface.
return new SecretKeySpec(engineGenerateSecret(), algorithm);
}
private abstract static class SimpleKeyAgreementSpi extends NativeKeyAgreementSpi {
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (!(params instanceof ECParameterSpec)) {
+ throw new InvalidAlgorithmParameterException();
+ }
+ engineInit(key, random);
+ this.params = params;
+ }
+
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
byte[] pubkey;
if (publicKey instanceof NativeECPublicKey) {
pubkey = ((NativeECPublicKey) publicKey).getData();
} else {
- pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), params.getCurve());
+ pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), ((ECParameterSpec) params).getCurve());
}
byte[] privkey;
if (privateKey instanceof NativeECPrivateKey) {
privkey = ((NativeECPrivateKey) privateKey).getData();
} else {
- privkey = ECUtil.toByteArray(privateKey.getS(), params.getCurve().getField().getFieldSize());
+ privkey = ECUtil.toByteArray(privateKey.getS(), ((ECParameterSpec) params).getCurve().getField().getFieldSize());
}
- return generateSecret(pubkey, privkey, params);
+ return generateSecret(pubkey, privkey, (ECParameterSpec) params);
}
abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
@@ -99,12 +100,21 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi {
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (!(params instanceof ECParameterSpec || params instanceof ECGenParameterSpec)) {
+ throw new InvalidAlgorithmParameterException();
+ }
+ engineInit(key, random);
+ this.params = params;
+ }
+
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
return generateSecret(publicKey, privateKey, params);
}
- abstract byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, ECParameterSpec params);
+ abstract byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params);
}
@@ -203,7 +213,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
@Override
- native byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, ECParameterSpec params);
+ native byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params);
}
public static class MscngECDHwithSHA1KDF extends Mscng {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index a284901..16736d7 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -28,9 +28,10 @@ typedef struct {
//Provider things
static jclass provider_class;
-#define KEYFLAG_IMPLICIT 0
-#define KEYFLAG_EXPLICIT 1
-#define KEYFLAG_NIST 2
+#define KEYFLAG_IMPLICIT 0 //Mscng native key, over named curve
+#define KEYFLAG_EXPLICIT 1 //Mscng native key, over explicit ecc parameters
+#define KEYFLAG_NIST 2 //Mscng native key, over NIST parameters, custom ECDH/ECDSA_P* algo
+#define KEYFLAG_OTHER 3 //Other key, explicit ecc parameters
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self) {
jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
@@ -797,11 +798,12 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty
}
switch (keyflag) {
- case 0:
- case 1:
+ case KEYFLAG_IMPLICIT:
+ case KEYFLAG_EXPLICIT:
+ case KEYFLAG_OTHER:
algo = algos[0];
break;
- case 2: {
+ case KEYFLAG_NIST: {
jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve);
@@ -834,7 +836,7 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty
}
switch (keyflag) {
- case 0: {
+ case KEYFLAG_IMPLICIT: {
jint meta_len = (*env)->GetArrayLength(env, meta);
jbyte *meta_data = (*env)->GetByteArrayElements(env, meta, NULL);
//if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, meta_data, meta_len, 0))) {
@@ -845,7 +847,8 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty
(*env)->ReleaseByteArrayElements(env, meta, meta_data, JNI_ABORT);
break;
}
- case 1: {
+ case KEYFLAG_EXPLICIT:
+ case KEYFLAG_OTHER: {
PBYTE curve;
ULONG curve_len = create_curve(env, params, &curve);
if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curve_len, 0))) {
@@ -861,15 +864,23 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty
}
static jint get_keyflag(JNIEnv *env, jobject key) {
- jclass key_class = (*env)->GetObjectClass(env, key);
- jmethodID get_flag = (*env)->GetMethodID(env, key_class, "getFlag", "()I");
- return (*env)->CallIntMethod(env, key, get_flag);
+ if ((*env)->IsInstanceOf(env, key, pubkey_class) || (*env)->IsInstanceOf(env, key, privkey_class)) {
+ jclass key_class = (*env)->GetObjectClass(env, key);
+ jmethodID get_flag = (*env)->GetMethodID(env, key_class, "getFlag", "()I");
+ return (*env)->CallIntMethod(env, key, get_flag);
+ } else {
+ return KEYFLAG_OTHER;
+ }
}
static jbyteArray get_meta(JNIEnv *env, jobject key) {
- jclass key_class = (*env)->GetObjectClass(env, key);
- jmethodID get_meta = (*env)->GetMethodID(env, key_class, "getMeta", "()[B");
- return (jbyteArray)(*env)->CallObjectMethod(env, key, get_meta);
+ if ((*env)->IsInstanceOf(env, key, pubkey_class) || (*env)->IsInstanceOf(env, key, privkey_class)) {
+ jclass key_class = (*env)->GetObjectClass(env, key);
+ jmethodID get_meta = (*env)->GetMethodID(env, key_class, "getMeta", "()[B");
+ return (jbyteArray)(*env)->CallObjectMethod(env, key, get_meta);
+ } else {
+ return NULL;
+ }
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jobject pubkey, jobject privkey, jobject params) {
@@ -897,6 +908,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
BCRYPT_ALG_HANDLE kaHandle = NULL;
jint pub_flag = get_keyflag(env, pubkey);
+ if (pub_flag == KEYFLAG_OTHER) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native public key.");
+ return NULL;
+ }
jbyteArray meta = get_meta(env, pubkey);
if (NT_FAILURE(status = init_use_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, pub_flag, meta, params))) {
@@ -906,27 +921,38 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
BCRYPT_KEY_HANDLE pkey = NULL;
BCRYPT_KEY_HANDLE skey = NULL;
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ jmethodID get_data_priv = (*env)->GetMethodID(env, pubkey_class, "getData", "()[B");
+ jbyteArray pubkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, pubkey, get_data_priv);
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey_barray);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey_barray, NULL);
if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair(pub)\n", status);
BCryptCloseAlgorithmProvider(kaHandle, 0);
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
return NULL;
}
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
jint priv_flag = get_keyflag(env, privkey);
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (priv_flag == KEYFLAG_OTHER) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native private key.");
+ return NULL;
+ }
+
+ jmethodID get_data_pub = (*env)->GetMethodID(env, privkey_class, "getData", "()[B");
+ jbyteArray privkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, privkey, get_data_pub);
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey_barray);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey_barray, NULL);
if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair(priv)\n", status);
BCryptCloseAlgorithmProvider(kaHandle, 0);
BCryptDestroyKey(pkey);
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, privkey_barray, priv_data, JNI_ABORT);
return NULL;
}
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, privkey_barray, priv_data, JNI_ABORT);
BCRYPT_SECRET_HANDLE ka = NULL;
@@ -1002,6 +1028,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
BCRYPT_ALG_HANDLE sigHandle = NULL;
jint keyflag = get_keyflag(env, privkey);
+ if (keyflag == KEYFLAG_OTHER) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native private key.");
+ return NULL;
+ }
jbyteArray meta = get_meta(env, privkey);
if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
@@ -1099,6 +1129,10 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
BCRYPT_ALG_HANDLE sigHandle = NULL;
jint keyflag = get_keyflag(env, pubkey);
+ if (keyflag == KEYFLAG_OTHER) { // TODO: This is not necessary
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native public key.");
+ return JNI_FALSE;
+ }
jbyteArray meta = get_meta(env, pubkey);
if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index b5cde43..dcdaa1b 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -819,7 +819,7 @@ extern "C" {
/*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
* Method: generateSecret
- * Signature: (Ljava/security/interfaces/ECPublicKey;Ljava/security/interfaces/ECPrivateKey;Ljava/security/spec/ECParameterSpec;)[B
+ * Signature: (Ljava/security/interfaces/ECPublicKey;Ljava/security/interfaces/ECPrivateKey;Ljava/security/spec/AlgorithmParameterSpec;)[B
*/
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret
(JNIEnv *, jobject, jobject, jobject, jobject);
--
cgit v1.3.1