aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2019-07-10 00:48:54 +0200
committerJ08nY2019-07-10 00:48:54 +0200
commit4969f63467fc92d55b8cb2448768ef43c6f74f02 (patch)
tree78cef50276dc34dcf217a6b804966bacf3a818b9
parent71d579ba134a4a11ac8c1647b3230843dc91fd8e (diff)
downloadECTester-feature/ippcp.tar.gz
ECTester-feature/ippcp.tar.zst
ECTester-feature/ippcp.zip
-rw-r--r--build-standalone.xml2
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java20
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java21
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/ippcp.c244
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/native.h54
5 files changed, 338 insertions, 3 deletions
diff --git a/build-standalone.xml b/build-standalone.xml
index c94588a..a686b11 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -194,6 +194,8 @@
<class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$Ippcp"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeECPublicKey$Ippcp"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Ippcp"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$Ippcp"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$Ippcp"/>
</javah>
</target>
</project>
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index b098792..662f32c 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -333,4 +333,24 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
+ public abstract static class Ippcp extends SimpleKeyAgreementSpi {
+ private String type;
+
+ public Ippcp(String type) {
+ this.type = type;
+ }
+
+ @Override
+ native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+
+ @Override
+ native SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm);
+ }
+
+ public static class IppcpECDH extends Ippcp {
+ public IppcpECDH() {
+ super("ECDH");
+ }
+ }
+
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
index 37e87bc..4db636e 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
@@ -461,6 +461,27 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
+ public abstract static class Ippcp extends SimpleSignatureSpi {
+ private String type;
+
+ public Ippcp(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 IppcpECDSAwithNONE extends Ippcp {
+
+ public IppcpECDSAwithNONE() {
+ super("NONEwithECDSA");
+ }
+ }
+
public abstract static class Mscng extends ExtendedSignatureSpi {
private String type;
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/ippcp.c b/src/cz/crcs/ectester/standalone/libs/jni/ippcp.c
index 27fadb1..2c5a747 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/ippcp.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/ippcp.c
@@ -14,6 +14,8 @@
#include <time.h>
#define USE_SPEEDUP 1
+#define VALIDATE_CURVE 1
+#define VALIDATE_POINT 1
static IppsPRNGState *prng_state;
static jclass provider_class;
@@ -66,8 +68,8 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_
INIT_PROVIDER(env, provider_class);
ADD_KPG(env, this, "EC", "Ippcp");
- // ADD_KA(env, self, "ECDH", "IppcplECDH");
- // ADD_SIG(env, self, "NONEwithECDSA", "IppcpECDSAwithNONE");
+ ADD_KA(env, this, "ECDH", "IppcpECDH");
+ ADD_SIG(env, this, "NONEwithECDSA", "IppcpECDSAwithNONE");
/* Init the PRNG. */
int prng_size;
@@ -283,7 +285,9 @@ static IppsECCPState *create_curve(JNIEnv *env, jobject params, int *keysize) {
jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
jint prime_bits = (*env)->CallIntMethod(env, p, get_bitlength);
- *keysize = prime_bits;
+ if (keysize) {
+ *keysize = prime_bits;
+ }
int size;
ippsECCPGetSize(prime_bits, &size);
@@ -335,6 +339,15 @@ static jobject create_ec_param_spec(JNIEnv *env, int keysize, IppsECCPState *cur
}
static jobject generate_from_curve(JNIEnv *env, int keysize, IppsECCPState *curve) {
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ return NULL;
+ }
+ }
+
IppsECCPPointState *point = new_point(keysize);
int ord_bits;
@@ -456,6 +469,231 @@ Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_g
}
}
+static IppsECCPPointState *bytearray_to_pubkey(JNIEnv *env, jbyteArray pubkey, jint keysize, IppsECCPState *curve) {
+ IppsBigNumState *x_bn = new_bn(keysize);
+ IppsBigNumState *y_bn = new_bn(keysize);
+
+ jint coord_size = (keysize + 7) / 8;
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ ippsSetOctString_BN(pub_data + 1, coord_size, x_bn);
+ ippsSetOctString_BN(pub_data + 1 + coord_size, coord_size, y_bn);
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+
+ IppsECCPPointState *pub = new_point(keysize);
+ ippsECCPSetPoint(x_bn, y_bn, pub, curve);
+ free(x_bn);
+ free(y_bn);
+ return pub;
+}
+
+static IppsBigNumState *bytearray_to_privkey(JNIEnv *env, jbyteArray privkey, IppsECCPState *curve) {
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+ IppsBigNumState *priv_bn = new_bn(ord_bits);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ ippsSetOctString_BN(priv_data, (*env)->GetArrayLength(env, privkey), priv_bn);
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ return priv_bn;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject this, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+ jint coord_size = ((*env)->GetArrayLength(env, pubkey) - 1) / 2;
+ jint keysize;
+ IppsECCPState *curve = create_curve(env, params, &keysize);
+
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ return NULL;
+ }
+ }
+ IppsECCPPointState *pub = bytearray_to_pubkey(env, pubkey, keysize, curve);
+
+ if (VALIDATE_POINT) {
+ IppECResult validation;
+ ippsECCPCheckPoint(pub, &validation, curve);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ free(pub);
+ return NULL;
+ }
+ }
+
+ IppsBigNumState *priv_bn = bytearray_to_privkey(env, privkey, curve);
+
+ IppsBigNumState *share = new_bn(keysize);
+
+ native_timing_start();
+ IppStatus err = ippsECCPSharedSecretDH(priv_bn, pub, share, curve);
+ native_timing_stop();
+
+ free(priv_bn);
+ free(pub);
+ free(curve);
+
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ return NULL;
+ }
+
+ jbyteArray result = (*env)->NewByteArray(env, coord_size);
+ jbyte *data = (*env)->GetByteArrayElements(env, result, NULL);
+ bn_get(share, data, coord_size);
+ (*env)->ReleaseBooleanArrayElements(env, result, data, 0);
+ free(share);
+ return result;
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2(JNIEnv *env, jobject this, jbyteArray pubkey, jbyteArray privkey, jobject params, jstring algorithm) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_sign(JNIEnv *env, jobject this, jbyteArray data, jbyteArray privkey, jobject params) {
+ jint keysize;
+ IppsECCPState *curve = create_curve(env, params, &keysize);
+
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ return NULL;
+ }
+ }
+ IppsBigNumState *priv_bn = bytearray_to_privkey(env, privkey, curve);
+
+ IppsECCPPointState *ephemeral_point = new_point(keysize);
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+ int ord_bytes = (ord_bits + 7) / 8;
+ IppsBigNumState *ephemeral_secret = new_bn(ord_bits);
+ IppsBigNumState *r = new_bn(ord_bits);
+ IppsBigNumState *s = new_bn(ord_bits);
+
+ jint data_size = (*env)->GetArrayLength(env, data);
+ IppsBigNumState *data_bn = new_bn(data_size * 8);
+ jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
+ ippsSetOctString_BN(data_data, data_size, data_bn);
+ (*env)->ReleaseBooleanArrayElements(env, data, data_data, JNI_ABORT);
+
+ jbyteArray result = NULL;
+ jbyte r_buf[ord_bytes];
+ jbyte s_buf[ord_bytes];
+
+ native_timing_start();
+ IppStatus err = ippsECCPGenKeyPair(ephemeral_secret, ephemeral_point, curve, prng_wrapper, prng_state);
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ err = ippsECCPSetKeyPair(ephemeral_secret, ephemeral_point, ippFalse, curve);
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ err = ippsECCPSignDSA(data_bn, priv_bn, r, s, curve);
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ native_timing_stop();
+
+ bn_get(r, r_buf, ord_bytes);
+ bn_get(s, s_buf, ord_bytes);
+
+ result = asn1_der_encode(env, r_buf, ord_bytes, s_buf, ord_bytes);
+
+error:
+ free(curve);
+ free(priv_bn);
+ free(ephemeral_point);
+ free(ephemeral_secret);
+ free(r);
+ free(s);
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_verify(JNIEnv *env, jobject this, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params) {
+ jint keysize;
+ IppsECCPState *curve = create_curve(env, params, &keysize);
+
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ return JNI_FALSE;
+ }
+ }
+ IppsECCPPointState *pub = bytearray_to_pubkey(env, pubkey, keysize, curve);
+
+ if (VALIDATE_POINT) {
+ IppECResult validation;
+ ippsECCPCheckPoint(pub, &validation, curve);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ free(pub);
+ return JNI_FALSE;
+ }
+ }
+
+ size_t r_len, s_len;
+ jbyte *r_data, *s_data;
+ bool decode = asn1_der_decode(env, signature, &r_data, &r_len, &s_data, &s_len);
+ if (!decode) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error decoding sig.");
+ free(curve);
+ free(pub);
+ return JNI_FALSE;
+ }
+
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+
+ IppsBigNumState *r = new_bn(ord_bits);
+ ippsSetOctString_BN(r_data, r_len, r);
+ free(r_data);
+ IppsBigNumState *s = new_bn(ord_bits);
+ ippsSetOctString_BN(s_data, s_len, s);
+ free(s_data);
+
+ jint data_size = (*env)->GetArrayLength(env, data);
+ IppsBigNumState *data_bn = new_bn(data_size * 8);
+ jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
+ ippsSetOctString_BN(data_data, data_size, data_bn);
+ (*env)->ReleaseBooleanArrayElements(env, data, data_data, JNI_ABORT);
+
+ IppECResult result;
+
+ native_timing_start();
+ ippsECCPSetKeyPair(NULL, pub, ippTrue, curve);
+ IppStatus err = ippsECCPVerifyDSA(data_bn, r, s, &result, curve);
+ native_timing_stop();
+
+ free(curve);
+ free(pub);
+ free(r);
+ free(s);
+
+ if (err == ippStsNoErr && result == ippECValid) {
+ return JNI_TRUE;
+ }
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ return JNI_FALSE;
+ }
+
+ return JNI_FALSE;
+}
+
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_supportsNativeTiming(JNIEnv *env, jobject this) {
return native_timing_supported();
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index 1648980..3cbc2d1 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -1791,3 +1791,57 @@ extern "C" {
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;Ljava/lang/String;)Ljavax/crypto/SecretKey;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif