aboutsummaryrefslogtreecommitdiff
path: root/standalone
diff options
context:
space:
mode:
authorJ08nY2024-03-28 17:37:06 +0100
committerJ08nY2024-03-28 17:37:06 +0100
commit59bcf047d2e141a2175aeaeb5bee3e9ce3e4d6ee (patch)
treea462bd5303dd399c5c1504d218c9c3b9bf78e365 /standalone
parent6cadd538804714c0e12c18a4fc483452b978aaad (diff)
downloadECTester-59bcf047d2e141a2175aeaeb5bee3e9ce3e4d6ee.tar.gz
ECTester-59bcf047d2e141a2175aeaeb5bee3e9ce3e4d6ee.tar.zst
ECTester-59bcf047d2e141a2175aeaeb5bee3e9ce3e4d6ee.zip
Diffstat (limited to 'standalone')
-rw-r--r--standalone/build.gradle.kts3
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp22
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.c15
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c5
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c20
-rw-r--r--standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java19
-rw-r--r--standalone/src/test/java/cz/crcs/ectester/standalone/OutputTests.java21
7 files changed, 95 insertions, 10 deletions
diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts
index c3c4b9a..5edeb04 100644
--- a/standalone/build.gradle.kts
+++ b/standalone/build.gradle.kts
@@ -38,6 +38,9 @@ tasks.named<Test>("test") {
useJUnitPlatform()
// Report is always generated after tests run
finalizedBy(tasks.jacocoTestReport)
+ jvmArgs(
+ "--add-exports", "jdk.crypto.ec/sun.security.ec=ALL-UNNAMED"
+ )
// Add wolfcrypt JNI lib path to LD_LIBRARY_PATH (as our native library loading does not handle it)
environment(
"LD_LIBRARY_PATH", "$rootDir/ext/wolfcrypt-jni/lib/:" + System.getenv("LD_LIBRARY_PATH")
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp
index c0d249c..c4441c3 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp
@@ -99,7 +99,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
return JNI_TRUE;
}
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_paramsSupported(JNIEnv *env, jobject self, jobject params){
+jboolean check_params(JNIEnv *env, jobject params) {
if (params == NULL) {
return JNI_FALSE;
}
@@ -128,6 +128,10 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
return JNI_FALSE;
}
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_paramsSupported(JNIEnv *env, jobject self, jobject params){
+ return check_params(env, params);
+}
+
static jobject biginteger_from_bigint(JNIEnv *env, const Botan::BigInt& bigint) {
std::vector<uint8_t> bigint_data = Botan::BigInt::encode(bigint);
jbyteArray bigint_array = env->NewByteArray(bigint_data.size());
@@ -305,6 +309,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
}
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
+ if (!check_params(env, params)) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+ }
Botan::EC_Group curve_group = group_from_params(env, params);
return generate_from_group(env, self, curve_group);
}
@@ -340,6 +348,10 @@ static std::string get_kdf(const std::string& type_str, size_t *kdf_bits) {
}
jbyteArray generate_secret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params, jstring algorithm) {
+ if (!check_params(env, params)) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+ }
Botan::EC_Group curve_group = group_from_params(env, params);
jsize privkey_length = env->GetArrayLength(privkey);
@@ -400,6 +412,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgr
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Botan_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params){
+ if (!check_params(env, params)) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+ }
Botan::EC_Group curve_group = group_from_params(env, params);
jclass botan_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Botan");
@@ -463,6 +479,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Botan_verify(JNIEnv *env, jobject self, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params){
+ if (!check_params(env, params)) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return JNI_FALSE;
+ }
Botan::EC_Group curve_group = group_from_params(env, params);
jclass botan_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Botan");
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.c
index 46286fd..1ace471 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.c
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.c
@@ -232,21 +232,18 @@ char *biginteger_to_hex(JNIEnv *env, jobject big, jint bytes) {
jstring big_string = (*env)->CallObjectMethod(env, big, to_string, (jint) 16);
jsize len = (*env)->GetStringUTFLength(env, big_string);
-#if defined(__WIN32__) || defined(_MSC_VER)
- char *raw_string = _alloca(len);
-#else
- char raw_string[len];
-#endif
- (*env)->GetStringUTFRegion(env, big_string, 0, len, raw_string);
+ const char *raw_string = (*env)->GetStringUTFChars(env, big_string, 0);
- char *result = calloc(bytes, 2);
+ char *result = calloc(bytes, sizeof(char) * 2);
if (len >= bytes) {
- return strncpy(result, raw_string, 2*bytes);
+ strncpy(result, raw_string, 2*bytes);
} else {
jsize diff = bytes - len;
for (jint i = 0; i < diff*2; ++i) {
result[i] = '0';
}
- return strncpy(result + diff*2, raw_string, 2*bytes);
+ strncpy(result + diff*2, raw_string, 2*bytes);
}
+ (*env)->ReleaseStringUTFChars(env, big_string, raw_string);
+ return result;
} \ No newline at end of file
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c
index a21c7cc..2566b2c 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c
@@ -249,6 +249,11 @@ static int create_curve(JNIEnv *env, jobject params, mbedtls_ecp_group *group) {
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)) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return 1;
+ }
+
jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
jobject p = (*env)->CallObjectMethod(env, field, get_p);
mpi_from_biginteger(env, p, &group->P);
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c
index 82592f1..4378e9b 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c
@@ -176,6 +176,10 @@ static ltc_ecc_set_type* create_curve(JNIEnv *env, jobject params) {
jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
jobject field = (*env)->CallObjectMethod(env, elliptic_curve, get_field);
+ if (!(*env)->IsInstanceOf(env, field, fp_field_class)) {
+ return NULL;
+ }
+
jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
jint bits = (*env)->CallIntMethod(env, field, get_bits);
jint bytes = (bits + 7) / 8;
@@ -284,6 +288,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject this, jobject params, jobject random){
if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
ltc_ecc_set_type *curve = create_curve(env, params);
+ if (!curve) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+ }
jobject result = generate_from_curve(env, curve);
free_curve(curve);
return result;
@@ -352,6 +360,10 @@ static jboolean pubkey_from_bytes(JNIEnv *env, jbyteArray pubkey, const ltc_ecc_
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject this, jbyteArray pubkey, jbyteArray privkey, jobject params){
ltc_ecc_set_type *curve = create_curve(env, params);
+ if (!curve) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+ }
ecc_key pub;
if (!pubkey_from_bytes(env, pubkey, curve, &pub)) {
@@ -395,6 +407,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgr
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_sign(JNIEnv *env, jobject this, jbyteArray data, jbyteArray privkey, jobject params) {
ltc_ecc_set_type *curve = create_curve(env, params);
+ if (!curve) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+ }
ecc_key priv;
if (!privkey_from_bytes(env, privkey, curve, &priv)) {
@@ -432,6 +448,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_verify(JNIEnv *env, jobject this, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params) {
ltc_ecc_set_type *curve = create_curve(env, params);
+ if (!curve) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return JNI_FALSE;
+ }
ecc_key pub;
if (!pubkey_from_bytes(env, pubkey, curve, &pub)) {
diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java
index 7105906..6e3dfed 100644
--- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java
+++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java
@@ -72,6 +72,25 @@ public class AppTests {
}
}
+ @SuppressWarnings("JUnitMalformedDeclaration")
+ @ParameterizedTest
+ @ValueSource(strings = {"Bouncy", "Sun", "libtomcrypt", "Botan", "Crypto++", "OpenSSL 3", "BoringSSL", "libgcrypt", "mbed TLS", "2021" /* IPPCP */, "Nettle", "LibreSSL", "wolfCrypt"})
+ @StdIo()
+ public void testVectorSuite(String libName, StdOut out) {
+ // TODO: Fix libgcrypt and IPPCP in handling binary field curves (reject them).
+ assumeFalse(libName.equals("libgcrypt") || libName.equals("2021"));
+
+ String[] args = new String[]{"test", "test-vectors", libName};
+ if (libName.equals("Botan") || libName.equals("Crypto++")) {
+ args = new String[]{"test", "--kpg-type", "ECDH", "test-vectors", libName};
+ }
+ ECTesterStandalone.main(args);
+ String sout = out.capturedString();
+ if (sout.contains("Exception")) {
+ System.err.printf("%s: Test vector suite has exceptions.%n", libName);
+ }
+ }
+
@ParameterizedTest
@ValueSource(strings = {"Bouncy", "Sun", "libtomcrypt", "Botan", "Crypto++", "OpenSSL 3", "BoringSSL", "libgcrypt", "mbed TLS", "2021" /* IPPCP */, "Nettle", "LibreSSL", "wolfCrypt"})
public void performanceSuite(String libName) {
diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/OutputTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/OutputTests.java
new file mode 100644
index 0000000..7218094
--- /dev/null
+++ b/standalone/src/test/java/cz/crcs/ectester/standalone/OutputTests.java
@@ -0,0 +1,21 @@
+package cz.crcs.ectester.standalone;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.junitpioneer.jupiter.StdIo;
+import org.junitpioneer.jupiter.StdOut;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+public class OutputTests {
+
+ @SuppressWarnings("JUnitMalformedDeclaration")
+ @ParameterizedTest
+ @ValueSource(strings = {"text", "xml", "yml"})
+ @StdIo()
+ public void formats(String format, StdOut out) {
+ ECTesterStandalone.main(new String[]{"test", "-f", format, "default", "Sun"});
+ String s = out.capturedString();
+ assertFalse(s.isEmpty());
+ }
+}