diff options
| author | J08nY | 2024-03-29 19:02:00 +0100 |
|---|---|---|
| committer | J08nY | 2024-03-29 19:02:00 +0100 |
| commit | 63beedc171116c5720b40d32daba34b753d6059c (patch) | |
| tree | 69af0fa9cd69102f213f760513077c11470bec6f | |
| parent | c048a5b348340d02e37eb9cc28d949896ff51975 (diff) | |
| download | ECTester-63beedc171116c5720b40d32daba34b753d6059c.tar.gz ECTester-63beedc171116c5720b40d32daba34b753d6059c.tar.zst ECTester-63beedc171116c5720b40d32daba34b753d6059c.zip | |
15 files changed, 245 insertions, 154 deletions
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java index 894da27..dd982aa 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java @@ -368,6 +368,12 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { native SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm); } + public static class LibresslECDH extends Libressl { + public LibresslECDH() { + super("ECDH"); + } + } + public abstract static class Nettle extends SimpleKeyAgreementSpi { private final String type; @@ -378,6 +384,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { @Override byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params) { try { + // TODO: OMG remove this monstrosity. AlgorithmParameters tmp = AlgorithmParameters.getInstance("EC"); tmp.init(params); ECGenParameterSpec spec = tmp.getParameterSpec(ECGenParameterSpec.class); @@ -420,10 +427,4 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { super("ECDH"); } } - public static class LibresslECDH extends Libressl { - public LibresslECDH() { - super("ECDH"); - } - } - } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c index bca2ead..4cc95a5 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c @@ -1,5 +1,8 @@ +#include "c_utils.h" +#include "c_timing.h" + #include "native.h" -#include <string.h> +#include <strings.h> #include <openssl/conf.h> #include <openssl/opensslv.h> @@ -12,9 +15,11 @@ #include <openssl/ecdh.h> #include <openssl/ecdsa.h> -#include "c_utils.h" -#include "c_timing.h" - +/* + * BoringSSL: + * - Supports prime field curves only. + * - Named curves and explicit params. + */ static jclass provider_class; @@ -113,6 +118,7 @@ static EC_GROUP *create_curve(JNIEnv *env, jobject params) { jobject field = (*env)->CallObjectMethod(env, elliptic_curve, get_field); if ((*env)->IsInstanceOf(env, field, f2m_field_class)) { + return NULL; } @@ -192,7 +198,8 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) { EC_GROUP *curve = create_curve(env, params); jboolean result = !curve; - EC_GROUP_free(curve); + if (curve) + EC_GROUP_free(curve); return result; } else if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) { jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); @@ -345,6 +352,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Boringssl_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) { if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) { EC_GROUP *curve = create_curve(env, params); + if (!curve) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return NULL; + } jobject result = generate_from_curve(env, curve); EC_GROUP_free(curve); return result; 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 c4441c3..3e266f6 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 @@ -16,6 +16,12 @@ #include "cpp_utils.hpp" #include "c_timing.h" +/* + * Botan: + * - Supports prime field curves only. + * - Named curves and explicit params. + */ + static jclass provider_class; static Botan::AutoSeeded_RNG rng; @@ -32,7 +38,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createP name_str.insert(0, "Botan "); jstring name = env->NewStringUTF(name_str.c_str()); - double version = strtod(v_str, NULL); + double version = strtod(v_str, nullptr); jstring info = env->NewStringUTF(info_str); return env->NewObject(provider_class, init, name, version, info); @@ -86,8 +92,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurv jobject result = env->NewObject(set_class, set_ctr); const std::set<std::string>& curves = Botan::EC_Group::known_named_groups(); - for (auto it = curves.begin(); it != curves.end(); ++it) { - std::string curve_name = *it; + for (const auto& curve_name : curves) { jstring name_str = env->NewStringUTF(curve_name.c_str()); env->CallBooleanMethod(result, set_add, name_str); } @@ -100,7 +105,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa } jboolean check_params(JNIEnv *env, jobject params) { - if (params == NULL) { + if (params == nullptr) { return JNI_FALSE; } @@ -117,8 +122,8 @@ jboolean check_params(JNIEnv *env, jobject params) { } else if (env->IsInstanceOf(params, ecgen_parameter_spec_class)) { const std::set<std::string>& curves = Botan::EC_Group::known_named_groups(); jmethodID get_name = env->GetMethodID(ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); - jstring name = (jstring) env->CallObjectMethod(params, get_name); - const char *utf_name = env->GetStringUTFChars(name, NULL); + auto name = (jstring) env->CallObjectMethod(params, get_name); + const char *utf_name = env->GetStringUTFChars(name, nullptr); std::string str_name(utf_name); env->ReleaseStringUTFChars(name, utf_name); if (curves.find(str_name) != curves.end()) { @@ -135,7 +140,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa 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()); - jbyte * bigint_bytes = env->GetByteArrayElements(bigint_array, NULL); + jbyte *bigint_bytes = env->GetByteArrayElements(bigint_array, nullptr); std::copy(bigint_data.begin(), bigint_data.end(), bigint_bytes); env->ReleaseByteArrayElements(bigint_array, bigint_bytes, 0); @@ -147,7 +152,7 @@ static Botan::BigInt bigint_from_biginteger(JNIEnv *env, jobject biginteger) { jmethodID to_byte_array = env->GetMethodID(biginteger_class, "toByteArray", "()[B"); jbyteArray byte_array = (jbyteArray) env->CallObjectMethod(biginteger, to_byte_array); jsize byte_length = env->GetArrayLength(byte_array); - jbyte *byte_data = env->GetByteArrayElements(byte_array, NULL); + jbyte *byte_data = env->GetByteArrayElements(byte_array, nullptr); Botan::BigInt result((unsigned char *) byte_data, byte_length); env->ReleaseByteArrayElements(byte_array, byte_data, JNI_ABORT); return result; @@ -199,7 +204,7 @@ static Botan::EC_Group group_from_params(JNIEnv *env, jobject params) { } else if (env->IsInstanceOf(params, ecgen_parameter_spec_class)) { jmethodID get_name = env->GetMethodID(ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); jstring name = (jstring) env->CallObjectMethod(params, get_name); - const char *utf_name = env->GetStringUTFChars(name, NULL); + const char *utf_name = env->GetStringUTFChars(name, nullptr); std::string curve_name(utf_name); env->ReleaseStringUTFChars(name, utf_name); return Botan::EC_Group(curve_name); @@ -240,7 +245,7 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr jclass botan_kpg_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Botan"); jfieldID type_id = env->GetFieldID(botan_kpg_class, "type", "Ljava/lang/String;"); jstring type = (jstring) env->GetObjectField(self, type_id); - const char* type_data = env->GetStringUTFChars(type, NULL); + const char* type_data = env->GetStringUTFChars(type, nullptr); std::string type_str(type_data); env->ReleaseStringUTFChars(type, type_data); @@ -259,7 +264,7 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr native_timing_stop(); } catch (Botan::Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); - return NULL; + return nullptr; } jobject ec_param_spec = params_from_group(env, group); @@ -268,7 +273,7 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr std::vector<uint8_t> pub_data = pub_point.encode(Botan::PointGFp::UNCOMPRESSED); jbyteArray pub_bytearray = env->NewByteArray(pub_data.size()); - jbyte *pub_bytes = env->GetByteArrayElements(pub_bytearray, NULL); + jbyte *pub_bytes = env->GetByteArrayElements(pub_bytearray, nullptr); std::copy(pub_data.begin(), pub_data.end(), pub_bytes); env->ReleaseByteArrayElements(pub_bytearray, pub_bytes, 0); @@ -280,7 +285,7 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr std::vector<uint8_t> priv_data = Botan::BigInt::encode(priv_scalar); jbyteArray priv_bytearray = env->NewByteArray(priv_data.size()); - jbyte *priv_bytes = env->GetByteArrayElements(priv_bytearray, NULL); + jbyte *priv_bytes = env->GetByteArrayElements(priv_bytearray, nullptr); std::copy(priv_data.begin(), priv_data.end(), priv_bytes); env->ReleaseByteArrayElements(priv_bytearray, priv_bytes, 0); @@ -295,8 +300,8 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random){ const std::set<std::string>& curves = Botan::EC_Group::known_named_groups(); - for (auto it = curves.begin(); it != curves.end(); ++it) { - Botan::EC_Group curve_group = Botan::EC_Group(*it); + for (const auto & curve : curves) { + Botan::EC_Group curve_group = Botan::EC_Group(curve); size_t curve_size = curve_group.get_p_bits(); if (curve_size == (size_t) keysize) { //generate on this group. Even thou no default groups are present... @@ -305,13 +310,13 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai } throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); - return NULL; + return nullptr; } 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; + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return nullptr; } Botan::EC_Group curve_group = group_from_params(env, params); return generate_from_group(env, self, curve_group); @@ -349,20 +354,20 @@ 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; + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return nullptr; } Botan::EC_Group curve_group = group_from_params(env, params); jsize privkey_length = env->GetArrayLength(privkey); - jbyte *privkey_data = env->GetByteArrayElements(privkey, NULL); + jbyte *privkey_data = env->GetByteArrayElements(privkey, nullptr); Botan::BigInt privkey_scalar((unsigned char *) privkey_data, privkey_length); env->ReleaseByteArrayElements(privkey, privkey_data, JNI_ABORT); Botan::ECDH_PrivateKey skey(rng, curve_group, privkey_scalar); jsize pubkey_length = env->GetArrayLength(pubkey); - jbyte *pubkey_data = env->GetByteArrayElements(pubkey, NULL); + jbyte *pubkey_data = env->GetByteArrayElements(pubkey, nullptr); Botan::PointGFp public_point = curve_group.OS2ECP((uint8_t*) pubkey_data, pubkey_length); env->ReleaseByteArrayElements(pubkey, pubkey_data, JNI_ABORT); @@ -372,7 +377,7 @@ jbyteArray generate_secret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteAr jclass botan_ka_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Botan"); jfieldID type_id = env->GetFieldID(botan_ka_class, "type", "Ljava/lang/String;"); jstring type = (jstring) env->GetObjectField(self, type_id); - const char *type_data = env->GetStringUTFChars(type, NULL); + const char *type_data = env->GetStringUTFChars(type, nullptr); std::string type_str(type_data); env->ReleaseStringUTFChars(type, type_data); @@ -388,10 +393,10 @@ jbyteArray generate_secret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteAr native_timing_stop(); } catch (Botan::Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); - return NULL; + return nullptr; } jbyteArray result = env->NewByteArray(derived.size()); - jbyte *result_data = env->GetByteArrayElements(result, NULL); + jbyte *result_data = env->GetByteArrayElements(result, nullptr); std::copy(derived.begin(), derived.end(), result_data); env->ReleaseByteArrayElements(result, result_data, 0); @@ -399,13 +404,13 @@ jbyteArray generate_secret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteAr } JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Botan_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params){ - return generate_secret(env, self, pubkey, privkey, params, NULL); + return generate_secret(env, self, pubkey, privkey, params, nullptr); } JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Botan_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params, jstring algorithm) { jbyteArray secret = generate_secret(env, self, pubkey, privkey, params, algorithm); - if (secret == NULL) { - return NULL; + if (secret == nullptr) { + return nullptr; } jmethodID spec_init = env->GetMethodID(secret_key_spec_class, "<init>", ("([BLjava/lang/String;)V")); return env->NewObject(secret_key_spec_class, spec_init, secret, algorithm); @@ -413,20 +418,20 @@ 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; + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return nullptr; } Botan::EC_Group curve_group = group_from_params(env, params); jclass botan_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Botan"); jfieldID type_id = env->GetFieldID(botan_sig_class, "type", "Ljava/lang/String;"); jstring type = (jstring) env->GetObjectField(self, type_id); - const char *type_data = env->GetStringUTFChars(type, NULL); + const char *type_data = env->GetStringUTFChars(type, nullptr); std::string type_str(type_data); env->ReleaseStringUTFChars(type, type_data); jsize privkey_length = env->GetArrayLength(privkey); - jbyte *privkey_bytes = env->GetByteArrayElements(privkey, NULL); + jbyte *privkey_bytes = env->GetByteArrayElements(privkey, nullptr); Botan::BigInt privkey_scalar((uint8_t*) privkey_bytes, privkey_length); env->ReleaseByteArrayElements(privkey, privkey_bytes, JNI_ABORT); @@ -457,7 +462,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig Botan::PK_Signer signer(*skey, rng, emsa, Botan::DER_SEQUENCE); jsize data_length = env->GetArrayLength(data); - jbyte *data_bytes = env->GetByteArrayElements(data, NULL); + jbyte *data_bytes = env->GetByteArrayElements(data, nullptr); std::vector<uint8_t> sig; try { native_timing_start(); @@ -466,12 +471,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig } catch (Botan::Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT); - return NULL; + return nullptr; } env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT); jbyteArray result = env->NewByteArray(sig.size()); - jbyte *result_data = env->GetByteArrayElements(result, NULL); + jbyte *result_data = env->GetByteArrayElements(result, nullptr); std::copy(sig.begin(), sig.end(), result_data); env->ReleaseByteArrayElements(result, result_data, 0); @@ -480,7 +485,7 @@ 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."); + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); return JNI_FALSE; } Botan::EC_Group curve_group = group_from_params(env, params); @@ -488,12 +493,12 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna jclass botan_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Botan"); jfieldID type_id = env->GetFieldID(botan_sig_class, "type", "Ljava/lang/String;"); jstring type = (jstring) env->GetObjectField(self, type_id); - const char *type_data = env->GetStringUTFChars(type, NULL); + const char *type_data = env->GetStringUTFChars(type, nullptr); std::string type_str(type_data); env->ReleaseStringUTFChars(type, type_data); jsize pubkey_length = env->GetArrayLength(pubkey); - jbyte *pubkey_data = env->GetByteArrayElements(pubkey, NULL); + jbyte *pubkey_data = env->GetByteArrayElements(pubkey, nullptr); Botan::PointGFp public_point = curve_group.OS2ECP((uint8_t*) pubkey_data, pubkey_length); env->ReleaseByteArrayElements(pubkey, pubkey_data, JNI_ABORT); @@ -525,8 +530,8 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna jsize data_length = env->GetArrayLength(data); jsize sig_length = env->GetArrayLength(signature); - jbyte *data_bytes = env->GetByteArrayElements(data, NULL); - jbyte *sig_bytes = env->GetByteArrayElements(signature, NULL); + jbyte *data_bytes = env->GetByteArrayElements(data, nullptr); + jbyte *sig_bytes = env->GetByteArrayElements(signature, nullptr); bool result; try { 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 1ace471..ac8c49d 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 @@ -127,16 +127,16 @@ jbyteArray asn1_der_encode(JNIEnv *env, const jbyte *r, size_t r_len, const jbyt jbyte s_length = (jbyte) s_len + (s[0] & 0x80 ? 1 : 0); // R and S are < 128 bytes, so 1 byte tag + 1 byte len + len bytes value - size_t seq_value_len = 2 + r_length + 2 + s_length; - size_t whole_len = seq_value_len; + jint seq_value_len = 2 + r_length + 2 + s_length; + jint whole_len = seq_value_len; // The SEQUENCE length might be >= 128, so more bytes of length - size_t seq_len_len = 0; + jint seq_len_len = 0; if (seq_value_len >= 128) { - size_t s = seq_value_len; + jint svl = seq_value_len; do { seq_len_len++; - } while ((s = s >> 8)); + } while ((svl = svl >> 8)); } // seq_len_len bytes for length and one for length of length whole_len += seq_len_len + 1; @@ -183,11 +183,11 @@ bool asn1_der_decode(JNIEnv *env, jbyteArray sig, jbyte **r_data, size_t *r_len, (*env)->ReleaseByteArrayElements(env, sig, data, JNI_ABORT); return false; } - size_t seq_value_len = 0; + jint seq_value_len = 0; if (!(data[i] & 0x80)) { seq_value_len = data[i++]; } else { - size_t seq_len_len = data[i++] & 0x7f; + jint seq_len_len = data[i++] & 0x7f; while (seq_len_len > 0) { seq_value_len |= (data[i++] << (seq_len_len - 1)); seq_len_len--; diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.h index f2f3f2f..93a11ed 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_utils.h @@ -57,11 +57,11 @@ char *biginteger_to_hex(JNIEnv *env, jobject big, jint bytes); /** * Some useful defines to init the provider. */ -#define INIT_PROVIDER(env, provider_class) jmethodID provider_put = (*env)->GetMethodID(env, provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") +#define INIT_PROVIDER(env, provider_class) jmethodID provider_put = (*(env))->GetMethodID(env, provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") #define ADD_PROPERTY(env, self, base_name, base_class, prop_name, prop_class) do { \ - jstring ec = (*env)->NewStringUTF(env, base_name prop_name); \ - jstring ec_value = (*env)->NewStringUTF(env, base_class prop_class); \ - (*env)->CallObjectMethod(env, self, provider_put, ec, ec_value); \ + jstring ec = (*(env))->NewStringUTF(env, base_name prop_name); \ + jstring ec_value = (*(env))->NewStringUTF(env, base_class prop_class); \ + (*(env))->CallObjectMethod(env, self, provider_put, ec, ec_value); \ } while (0) #define ADD_KPG(env, self, kpg_name, kpg_class) ADD_PROPERTY(env, self, "KeyPairGenerator.", "cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$", kpg_name, kpg_class) #define ADD_KA(env, self, ka_name, ka_class) ADD_PROPERTY(env, self, "KeyAgreement.", "cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$", ka_name, ka_class) diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp index eb782b7..9bb99a3 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp @@ -72,6 +72,12 @@ using CryptoPP::Integer; #include "cpp_utils.hpp" #include "c_timing.h" +/* + * Crypto++: +* - Supports both prime field and binary field curves. +* - Named curves (OID) and explicit params. + */ + static jclass provider_class; static AutoSeededRandomPool rng; @@ -163,8 +169,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getC std::vector<OID> all_oids = get_all_curve_oids(); - for (auto oid = all_oids.begin(); oid != all_oids.end(); ++oid) { - jstring name_str = env->NewStringUTF(oid_to_str(*oid).c_str()); + for (auto & all_oid : all_oids) { + jstring name_str = env->NewStringUTF(oid_to_str(all_oid).c_str()); env->CallBooleanMethod(result, set_add, name_str); } @@ -173,16 +179,16 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getC JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_keysizeSupported(JNIEnv *env, jobject self, jint keysize){ std::vector<OID> ecp_oids = get_curve_oids<ECP>(); - for (auto oid = ecp_oids.begin(); oid != ecp_oids.end(); ++oid) { - DL_GroupParameters_EC<ECP> group(*oid); + for (auto & ecp_oid : ecp_oids) { + DL_GroupParameters_EC<ECP> group(ecp_oid); if (((jint) group.GetCurve().GetField().MaxElementBitLength()) == keysize) { return JNI_TRUE; } } std::vector<OID> e2n_oids = get_curve_oids<EC2N>(); - for (auto oid = e2n_oids.begin(); oid != e2n_oids.end(); ++oid) { - DL_GroupParameters_EC<EC2N> group(*oid); + for (auto & e2n_oid : e2n_oids) { + DL_GroupParameters_EC<EC2N> group(e2n_oid); if (((jint) group.GetCurve().FieldSize().ConvertToLong()) == keysize) { return JNI_TRUE; } @@ -191,7 +197,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa } JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_paramsSupported(JNIEnv *env, jobject self, jobject params){ - if (params == NULL) { + if (params == nullptr) { return JNI_FALSE; } @@ -202,13 +208,13 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa // Compare with OIDs I guess? jmethodID get_name = env->GetMethodID(ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); jstring name = (jstring) env->CallObjectMethod(params, get_name); - const char *utf_name = env->GetStringUTFChars(name, NULL); + const char *utf_name = env->GetStringUTFChars(name, nullptr); std::string str_name(utf_name); env->ReleaseStringUTFChars(name, utf_name); std::vector<OID> all_oids = get_all_curve_oids(); - for (auto oid = all_oids.begin(); oid != all_oids.end(); ++oid) { - std::string oid_s = oid_to_str(*oid); + for (auto & all_oid : all_oids) { + std::string oid_s = oid_to_str(all_oid); if (str_name == oid_s) { return JNI_TRUE; } @@ -222,7 +228,7 @@ static Integer integer_from_biginteger(JNIEnv *env, jobject bigint) { jbyteArray byte_array = (jbyteArray) env->CallObjectMethod(bigint, to_byte_array); jsize byte_length = env->GetArrayLength(byte_array); - jbyte *byte_data = env->GetByteArrayElements(byte_array, NULL); + jbyte *byte_data = env->GetByteArrayElements(byte_array, nullptr); Integer result((byte *) byte_data, (size_t) byte_length); env->ReleaseByteArrayElements(byte_array, byte_data, JNI_ABORT); return result; @@ -231,7 +237,7 @@ static Integer integer_from_biginteger(JNIEnv *env, jobject bigint) { static jobject biginteger_from_integer(JNIEnv *env, const Integer &integer) { jbyteArray byte_array = (jbyteArray) env->NewByteArray(integer.MinEncodedSize()); - jbyte *bigint_bytes = env->GetByteArrayElements(byte_array, NULL); + jbyte *bigint_bytes = env->GetByteArrayElements(byte_array, nullptr); integer.Encode((byte *) bigint_bytes, integer.MinEncodedSize()); env->ReleaseByteArrayElements(byte_array, bigint_bytes, 0); @@ -243,7 +249,7 @@ static jobject biginteger_from_polmod2(JNIEnv *env, const PolynomialMod2 &polmod jmethodID biginteger_init = env->GetMethodID(biginteger_class, "<init>", "(I[B)V"); jbyteArray mod_array = env->NewByteArray(polmod.MinEncodedSize()); - jbyte *mod_data = env->GetByteArrayElements(mod_array, NULL); + jbyte *mod_data = env->GetByteArrayElements(mod_array, nullptr); polmod.Encode((byte *) mod_data, polmod.MinEncodedSize()); env->ReleaseByteArrayElements(mod_array, mod_data, 0); @@ -301,15 +307,15 @@ static std::unique_ptr<DL_GroupParameters_EC<ECP>> fp_group_from_params(JNIEnv * } else if (env->IsInstanceOf(params, ecgen_parameter_spec_class)) { jmethodID get_name = env->GetMethodID(ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); jstring name = (jstring) env->CallObjectMethod(params, get_name); - const char *utf_name = env->GetStringUTFChars(name, NULL); + const char *utf_name = env->GetStringUTFChars(name, nullptr); std::string str_name(utf_name); env->ReleaseStringUTFChars(name, utf_name); std::vector<OID> ecp_oids = get_curve_oids<ECP>(); - for (auto oid = ecp_oids.begin(); oid != ecp_oids.end(); ++oid) { - std::string oid_s = oid_to_str(*oid); + for (auto & ecp_oid : ecp_oids) { + std::string oid_s = oid_to_str(ecp_oid); if (str_name == oid_s) { - return std::make_unique<DL_GroupParameters_EC<ECP>>(*oid); + return std::make_unique<DL_GroupParameters_EC<ECP>>(ecp_oid); } } } @@ -357,7 +363,7 @@ static std::unique_ptr<DL_GroupParameters_EC<EC2N>> f2m_group_from_params(JNIEnv jmethodID get_midterms = env->GetMethodID(f2m_field_class, "getMidTermsOfReductionPolynomial", "()[I"); jintArray midterms = (jintArray) env->CallObjectMethod(field, get_midterms); jsize midterm_length = env->GetArrayLength(midterms); - jint *midterm_data = env->GetIntArrayElements(midterms, NULL); + jint *midterm_data = env->GetIntArrayElements(midterms, nullptr); jmethodID get_m = env->GetMethodID(f2m_field_class, "getM", "()I"); jint m = env->CallIntMethod(field, get_m); @@ -375,11 +381,11 @@ static std::unique_ptr<DL_GroupParameters_EC<EC2N>> f2m_group_from_params(JNIEnv jmethodID to_byte_array = env->GetMethodID(biginteger_class, "toByteArray", "()[B"); jbyteArray a_array = (jbyteArray) env->CallObjectMethod(a, to_byte_array); jsize a_length = env->GetArrayLength(a_array); - jbyte *a_data = env->GetByteArrayElements(a_array, NULL); + jbyte *a_data = env->GetByteArrayElements(a_array, nullptr); jbyteArray b_array = (jbyteArray) env->CallObjectMethod(b, to_byte_array); jsize b_length = env->GetArrayLength(b_array); - jbyte *b_data = env->GetByteArrayElements(b_array, NULL); + jbyte *b_data = env->GetByteArrayElements(b_array, nullptr); EC2N curve(*base_field, EC2N::FieldElement((byte *) a_data, (size_t) a_length), EC2N::FieldElement((byte *) b_data, (size_t) b_length)); env->ReleaseByteArrayElements(a_array, a_data, JNI_ABORT); @@ -387,13 +393,13 @@ static std::unique_ptr<DL_GroupParameters_EC<EC2N>> f2m_group_from_params(JNIEnv jbyteArray gx_array = (jbyteArray) env->CallObjectMethod(gx, to_byte_array); jsize gx_length = env->GetArrayLength(gx_array); - jbyte *gx_data = env->GetByteArrayElements(gx_array, NULL); + jbyte *gx_data = env->GetByteArrayElements(gx_array, nullptr); PolynomialMod2 gxm((byte *) gx_data, (size_t) gx_length); env->ReleaseByteArrayElements(gx_array, gx_data, JNI_ABORT); jbyteArray gy_array = (jbyteArray) env->CallObjectMethod(gy, to_byte_array); jsize gy_length = env->GetArrayLength(gy_array); - jbyte *gy_data = env->GetByteArrayElements(gy_array, NULL); + jbyte *gy_data = env->GetByteArrayElements(gy_array, nullptr); PolynomialMod2 gym((byte *) gy_data, (size_t) gy_length); env->ReleaseByteArrayElements(gy_array, gy_data, JNI_ABORT); @@ -403,15 +409,15 @@ static std::unique_ptr<DL_GroupParameters_EC<EC2N>> f2m_group_from_params(JNIEnv } else if (env->IsInstanceOf(params, ecgen_parameter_spec_class)) { jmethodID get_name = env->GetMethodID(ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;"); jstring name = (jstring) env->CallObjectMethod(params, get_name); - const char *utf_name = env->GetStringUTFChars(name, NULL); + const char *utf_name = env->GetStringUTFChars(name, nullptr); std::string str_name(utf_name); env->ReleaseStringUTFChars(name, utf_name); std::vector<OID> e2n_oids = get_curve_oids<EC2N>(); - for (auto oid = e2n_oids.begin(); oid != e2n_oids.end(); ++oid) { - std::string oid_s = oid_to_str(*oid); + for (auto & e2n_oid : e2n_oids) { + std::string oid_s = oid_to_str(e2n_oid); if (str_name == oid_s) { - return std::make_unique<DL_GroupParameters_EC<EC2N>>(*oid); + return std::make_unique<DL_GroupParameters_EC<EC2N>>(e2n_oid); } } } @@ -436,13 +442,13 @@ template <class EC> jobject finish_params(JNIEnv *env, jobject field, jobject a, } template <class EC> jobject params_from_group(JNIEnv *env, DL_GroupParameters_EC<EC> group) { - return NULL; + return nullptr; } template <> jobject params_from_group<ECP>(JNIEnv *env, DL_GroupParameters_EC<ECP> group) { - ECP curve = group.GetCurve(); + const ECP& curve = group.GetCurve(); jmethodID fp_field_init = env->GetMethodID(fp_field_class, "<init>", "(Ljava/math/BigInteger;)V"); - ModularArithmetic mod = curve.GetField(); + const ModularArithmetic& mod = curve.GetField(); jobject p = biginteger_from_integer(env, mod.GetModulus()); jobject a = biginteger_from_integer(env, curve.GetA()); jobject b = biginteger_from_integer(env, curve.GetB()); @@ -456,7 +462,7 @@ template <> jobject params_from_group<ECP>(JNIEnv *env, DL_GroupParameters_EC<EC } template <> jobject params_from_group<EC2N>(JNIEnv *env, DL_GroupParameters_EC<EC2N> group) { - EC2N curve = group.GetCurve(); + const EC2N& curve = group.GetCurve(); PolynomialMod2 mod = curve.GetField().GetModulus(); int m = mod.Degree(); unsigned int coeff_count = mod.CoefficientCount(); @@ -472,9 +478,9 @@ template <> jobject params_from_group<EC2N>(JNIEnv *env, DL_GroupParameters_EC<E ks = env->NewIntArray(3); to_find = 3; } else { - return NULL; + return nullptr; } - jint *ks_data = env->GetIntArrayElements(ks, NULL); + jint *ks_data = env->GetIntArrayElements(ks, nullptr); for (int i = m - 1; i > 0 && found < to_find; --i) { if (mod.GetCoefficient(i) == 1) { ks_data[found++] = i; @@ -504,11 +510,11 @@ template <class EC> jobject generate_from_group(JNIEnv *env, DL_GroupParameters_ native_timing_stop(); } catch (Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); - return NULL; + return nullptr; } jbyteArray pub_bytearray = env->NewByteArray(pub.SizeInBytes()); - jbyte *pub_bytes = env->GetByteArrayElements(pub_bytearray, NULL); + jbyte *pub_bytes = env->GetByteArrayElements(pub_bytearray, nullptr); std::copy(pub.BytePtr(), pub.BytePtr()+pub.SizeInBytes(), pub_bytes); env->ReleaseByteArrayElements(pub_bytearray, pub_bytes, 0); @@ -517,7 +523,7 @@ template <class EC> jobject generate_from_group(JNIEnv *env, DL_GroupParameters_ jobject pubkey = env->NewObject(pubkey_class, ec_pub_init, pub_bytearray, ec_pub_param_spec); jbyteArray priv_bytearray = env->NewByteArray(priv.SizeInBytes()); - jbyte *priv_bytes = env->GetByteArrayElements(priv_bytearray, NULL); + jbyte *priv_bytes = env->GetByteArrayElements(priv_bytearray, nullptr); std::copy(priv.BytePtr(), priv.BytePtr()+priv.SizeInBytes(), priv_bytes); env->ReleaseByteArrayElements(priv_bytearray, priv_bytes, 0); @@ -532,8 +538,8 @@ template <class EC> jobject generate_from_group(JNIEnv *env, DL_GroupParameters_ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random){ std::vector<OID> ecp_oids = get_curve_oids<ECP>(); - for (auto oid = ecp_oids.begin(); oid != ecp_oids.end(); ++oid) { - DL_GroupParameters_EC<ECP> group(*oid); + for (auto & ecp_oid : ecp_oids) { + DL_GroupParameters_EC<ECP> group(ecp_oid); if (((jint) group.GetCurve().GetField().MaxElementBitLength()) == keysize) { jobject params = params_from_group(env, group); return generate_from_group<ECP>(env, group, params); @@ -541,14 +547,14 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai } std::vector<OID> e2n_oids = get_curve_oids<EC2N>(); - for (auto oid = e2n_oids.begin(); oid != e2n_oids.end(); ++oid) { - DL_GroupParameters_EC<EC2N> group(*oid); + for (auto & e2n_oid : e2n_oids) { + DL_GroupParameters_EC<EC2N> group(e2n_oid); if ((jint) group.GetCurve().FieldSize().ConvertToLong() == keysize) { jobject params = params_from_group(env, group); return generate_from_group<EC2N>(env, group, params); } } - return NULL; + return nullptr; } JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) { @@ -559,17 +565,17 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai } else { return generate_from_group<ECP>(env, *ecp_group, params); } - return NULL; + return nullptr; } JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Cryptopp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) { jsize privkey_length = env->GetArrayLength(privkey); - jbyte *privkey_data = env->GetByteArrayElements(privkey, NULL); + jbyte *privkey_data = env->GetByteArrayElements(privkey, nullptr); SecByteBlock private_key((byte *) privkey_data, privkey_length); env->ReleaseByteArrayElements(privkey, privkey_data, JNI_ABORT); jsize pubkey_length = env->GetArrayLength(pubkey); - jbyte *pubkey_data = env->GetByteArrayElements(pubkey, NULL); + jbyte *pubkey_data = env->GetByteArrayElements(pubkey, nullptr); SecByteBlock public_key((byte *) pubkey_data, pubkey_length); env->ReleaseByteArrayElements(pubkey, pubkey_data, JNI_ABORT); @@ -587,7 +593,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey native_timing_stop(); } catch (Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); - return NULL; + return nullptr; } } else { ECDH<ECP>::Domain dh_agreement(*ecp_group); @@ -599,16 +605,16 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey native_timing_stop(); } catch (Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); - return NULL; + return nullptr; } } if (!success) { throw_new(env, "java/security/GeneralSecurityException", "Agreement was unsuccessful."); - return NULL; + return nullptr; } jbyteArray result = env->NewByteArray(secret->size()); - jbyte *result_data = env->GetByteArrayElements(result, NULL); + jbyte *result_data = env->GetByteArrayElements(result, nullptr); std::copy(secret->begin(), secret->end(), result_data); env->ReleaseByteArrayElements(result, result_data, 0); @@ -617,7 +623,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Cryptopp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params, jstring algorithm){ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported."); - return NULL; + return nullptr; } template <class EC, class H> @@ -630,7 +636,7 @@ jbyteArray sign_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray std::string signature(signer.MaxSignatureLength(), 0); jsize data_length = env->GetArrayLength(data); - jbyte *data_bytes = env->GetByteArrayElements(data, NULL); + jbyte *data_bytes = env->GetByteArrayElements(data, nullptr); native_timing_start(); size_t len = signer.SignMessage(rng, (byte *)data_bytes, data_length, (byte *)signature.c_str()); native_timing_stop(); @@ -641,7 +647,7 @@ jbyteArray sign_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray size_t sig_len = DSAConvertSignatureFormat(sig, sizeof(sig), DSA_DER, (byte *)signature.c_str(), len, DSA_P1363); jbyteArray result = env->NewByteArray(sig_len); - jbyte *result_bytes = env->GetByteArrayElements(result, NULL); + jbyte *result_bytes = env->GetByteArrayElements(result, nullptr); std::copy(sig, sig+sig_len, result_bytes); env->ReleaseByteArrayElements(result, result_bytes, 0); @@ -652,16 +658,16 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig jclass cryptopp_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Cryptopp"); jfieldID type_id = env->GetFieldID(cryptopp_sig_class, "type", "Ljava/lang/String;"); jstring type = (jstring) env->GetObjectField(self, type_id); - const char *type_data = env->GetStringUTFChars(type, NULL); + const char *type_data = env->GetStringUTFChars(type, nullptr); std::string type_str(type_data); env->ReleaseStringUTFChars(type, type_data); jsize privkey_length = env->GetArrayLength(privkey); - jbyte *privkey_data = env->GetByteArrayElements(privkey, NULL); + jbyte *privkey_data = env->GetByteArrayElements(privkey, nullptr); Integer private_key_x((byte *) privkey_data, (size_t) privkey_length); env->ReleaseByteArrayElements(privkey, privkey_data, JNI_ABORT); - jbyteArray result = NULL; + jbyteArray result = nullptr; std::unique_ptr<DL_GroupParameters_EC<ECP>> ecp_group = fp_group_from_params(env, params); if (ecp_group == nullptr) { @@ -698,7 +704,7 @@ template <class EC, class H> jboolean verify_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray data, jbyteArray signature, jbyteArray pubkey) { typename EC::Point pkey_point; jsize pubkey_length = env->GetArrayLength(pubkey); - jbyte *pubkey_data = env->GetByteArrayElements(pubkey, NULL); + jbyte *pubkey_data = env->GetByteArrayElements(pubkey, nullptr); group.GetCurve().DecodePoint(pkey_point, (byte *)pubkey_data, pubkey_length); env->ReleaseByteArrayElements(pubkey, pubkey_data, JNI_ABORT); @@ -710,14 +716,14 @@ jboolean verify_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray size_t bytes = (bit_length + 7)/8; jsize sig_length = env->GetArrayLength(signature); - jbyte *sig_bytes = env->GetByteArrayElements(signature, NULL); + jbyte *sig_bytes = env->GetByteArrayElements(signature, nullptr); byte sig[bytes * 2]; size_t sig_len = DSAConvertSignatureFormat(sig, bytes * 2, DSA_P1363, (byte *)sig_bytes, sig_length, DSA_DER); env->ReleaseByteArrayElements(signature, sig_bytes, JNI_ABORT); jsize data_length = env->GetArrayLength(data); - jbyte *data_bytes = env->GetByteArrayElements(data, NULL); + jbyte *data_bytes = env->GetByteArrayElements(data, nullptr); native_timing_start(); bool result = verifier.VerifyMessage((byte *)data_bytes, data_length, sig, sig_len); native_timing_stop(); @@ -730,7 +736,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna jclass cryptopp_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Cryptopp"); jfieldID type_id = env->GetFieldID(cryptopp_sig_class, "type", "Ljava/lang/String;"); jstring type = (jstring) env->GetObjectField(self, type_id); - const char *type_data = env->GetStringUTFChars(type, NULL); + const char *type_data = env->GetStringUTFChars(type, nullptr); std::string type_str(type_data); env->ReleaseStringUTFChars(type, type_data); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c index 5d29d2c..ef62fbf 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c @@ -1,10 +1,18 @@ +#include "c_utils.h" +#include "c_timing.h" + #include "native.h" #include <stdio.h> #include <ctype.h> #include <stdbool.h> #include <gcrypt.h> -#include "c_utils.h" -#include "c_timing.h" + +/* + * libgcrypt: + * - Supports prime field curves only. + * - Named curves and (likely) explicit params for keygen. + * - TODO: Add support for explicit params in keygen. + */ static jclass provider_class; @@ -65,7 +73,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_GcryptLib_getCur const char *name; unsigned int nbits; - for (size_t i = 0; (name = gcry_pk_get_curve(NULL, i, &nbits)); i++){ + for (jint i = 0; (name = gcry_pk_get_curve(NULL, i, &nbits)); i++){ jstring curve_name = (*env)->NewStringUTF(env, name); (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name); } @@ -77,7 +85,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa const char *name; unsigned int nbits; - for (size_t i = 0; (name = gcry_pk_get_curve(NULL, i, &nbits)); i++){ + for (jint i = 0; (name = gcry_pk_get_curve(NULL, i, &nbits)); i++){ if (nbits == keysize) { return JNI_TRUE; } @@ -133,7 +141,7 @@ static gcry_mpi_t bytearray_to_mpi(JNIEnv *env, jbyteArray array) { gcry_mpi_t result; - size_t length = (*env)->GetArrayLength(env, array); + jsize length = (*env)->GetArrayLength(env, array); jbyte data[length + 1]; data[0] = 0; (*env)->GetByteArrayRegion(env, array, 0, length, data + 1); @@ -354,6 +362,10 @@ static gcry_sexp_t create_key(JNIEnv *env, jobject ec_param_spec, const char *ke 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; @@ -437,6 +449,10 @@ static gcry_sexp_t create_privkey(JNIEnv *env, jobject ec_param_spec, jbyteArray JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Gcrypt_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject this, jbyteArray pubkey, jbyteArray privkey, jobject params) { jbyteArray result = NULL; gcry_sexp_t pub = create_pubkey(env, params, pubkey); + if (!pub) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return NULL; + } gcry_mpi_t priv = bytearray_to_mpi(env, privkey); gcry_sexp_t enc_sexp; @@ -547,6 +563,10 @@ static void get_sign_data_sexp(JNIEnv *env, gcry_sexp_t *result, jobject this, j JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Gcrypt_sign(JNIEnv *env, jobject this, jbyteArray data, jbyteArray privkey, jobject params) { jbyteArray result = NULL; gcry_sexp_t priv_sexp = create_privkey(env, params, NULL, privkey); + if (!priv_sexp) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return NULL; + } gcry_sexp_t data_sexp; get_sign_data_sexp(env, &data_sexp, this, data); @@ -582,6 +602,10 @@ release_init: JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Gcrypt_verify(JNIEnv *env, jobject this, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) { jboolean result = JNI_FALSE; gcry_sexp_t pub_sexp = create_pubkey(env, params, pubkey); + if (!pub_sexp) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return JNI_FALSE; + } gcry_sexp_t data_sexp; get_sign_data_sexp(env, &data_sexp, this, data); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c index 98a4c36..decf496 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c @@ -1,3 +1,6 @@ +#include "c_timing.h" +#include "c_utils.h" + #include <stdint.h> #include <stdlib.h> #include <string.h> @@ -5,9 +8,6 @@ #include <ippcp.h> -#include "c_timing.h" -#include "c_utils.h" - #define _POSIX_C_SOURCE 200809L #include <stdio.h> @@ -55,12 +55,13 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_createP jmethodID init = (*env)->GetMethodID(env, local_provider_class, "<init>", "(Ljava/lang/String;DLjava/lang/String;)V"); const IppLibraryVersion *lib = ippcpGetLibVersion(); - jstring name = (*env)->NewStringUTF(env, lib->Name); + char full_name[strlen("ippcp ") + strlen(lib->Name) + 1]; + strcpy(full_name, "ippcp "); + strcat(full_name, lib->Name); + jstring name = (*env)->NewStringUTF(env, full_name); double version = (double)lib->major + ((double)lib->minor / 10); jstring info = (*env)->NewStringUTF(env, lib->Version); - // printf("%s\n%s\n%d.%d.%d.%d\n", lib->Name, lib->Version, lib->major, lib->minor, lib->majorBuild, lib->build); - return (*env)->NewObject(env, provider_class, init, name, version, info); } @@ -255,6 +256,10 @@ static IppsECCPState *create_curve(JNIEnv *env, jobject params, int *keysize) { 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 NULL; + } + jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I"); jint bits = (*env)->CallIntMethod(env, field, get_bits); @@ -293,12 +298,31 @@ static IppsECCPState *create_curve(JNIEnv *env, jobject params, int *keysize) { } int size; - ippsECCPGetSize(bits, &size); + IppStatus err = ippsECCPGetSize(bits, &size); + if (err != ippStsNoErr) { + goto err_out; + } IppsECCPState *result = malloc(size); - ippsECCPInit(bits, result); - ippsECCPSet(p_bn, a_bn, b_bn, gx_bn, gy_bn, n_bn, h, result); - + err = ippsECCPInit(bits, result); + if (err != ippStsNoErr) { + free(result); + goto err_out; + } + err = ippsECCPSet(p_bn, a_bn, b_bn, gx_bn, gy_bn, n_bn, h, result); + if (err != ippStsNoErr) { + free(result); + goto err_out; + } return result; + +err_out: + free(p_bn); + free(a_bn); + free(b_bn); + free(gx_bn); + free(gy_bn); + free(n_bn); + return NULL; } static jobject create_ec_param_spec(JNIEnv *env, int keysize, IppsECCPState *curve) { @@ -451,6 +475,10 @@ Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_g if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) { int keysize; IppsECCPState *curve = create_curve(env, params, &keysize); + if (!curve) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return NULL; + } jobject result = generate_from_curve(env, keysize, curve); free(curve); return result; @@ -503,6 +531,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey jint coord_size = ((*env)->GetArrayLength(env, pubkey) - 1) / 2; jint keysize; IppsECCPState *curve = create_curve(env, params, &keysize); + if (!curve) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return NULL; + } if (VALIDATE_CURVE) { IppECResult validation; @@ -559,6 +591,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgr 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 (!curve) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return NULL; + } if (VALIDATE_CURVE) { IppECResult validation; @@ -625,6 +661,10 @@ error: 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 (!curve) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); + return JNI_FALSE; + } if (VALIDATE_CURVE) { IppECResult validation; diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c index be1b749..398ad1e 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c @@ -1,3 +1,6 @@ +#include "c_utils.h" +#include "c_timing.h" + #include "native.h" #include <string.h> @@ -11,8 +14,7 @@ #include <openssl/ecdh.h> #include <openssl/ecdsa.h> -#include "c_utils.h" -#include "c_timing.h" + static jclass provider_class; 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 2566b2c..ab556d8 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 @@ -1,3 +1,6 @@ +#include "c_utils.h" +#include "c_timing.h" + #include "native.h" #include <string.h> #include <stdio.h> @@ -10,8 +13,6 @@ #include <mbedtls/entropy.h> #include <mbedtls/ctr_drbg.h> -#include "c_utils.h" -#include "c_timing.h" static mbedtls_ctr_drbg_context ctr_drbg; static mbedtls_entropy_context entropy; @@ -228,7 +229,7 @@ static jobject create_ec_param_spec(JNIEnv *env, const mbedtls_ecp_group *group) size_t point_len = 2 * mbedtls_mpi_size(&group->P) + 1; jbyteArray g_bytes = (*env)->NewByteArray(env, (jint) point_len); jbyte *g_data = (*env)->GetByteArrayElements(env, g_bytes, NULL); - mbedtls_ecp_point_write_binary(group, &group->G, MBEDTLS_ECP_PF_UNCOMPRESSED, &point_len, g_data, point_len); + mbedtls_ecp_point_write_binary(group, &group->G, MBEDTLS_ECP_PF_UNCOMPRESSED, &point_len, (unsigned char *) g_data, point_len); (*env)->ReleaseByteArrayElements(env, g_bytes, g_data, 0); jobject g = (*env)->CallStaticObjectMethod(env, ecutil_class, from_X962, g_bytes, elliptic_curve); @@ -277,14 +278,14 @@ static int create_curve(JNIEnv *env, jobject params, mbedtls_ecp_group *group) { jbyte *point_data = (*env)->GetByteArrayElements(env, point_array, NULL); // The mbedtls_ecp_point_read_binary function we use to setup the generator actually // internally relies on the group generator already being set to a sane value. - // Thus we need to set it to the point at infinity first, only then can we load the + // Thus, we need to set it to the point at infinity first, only then can we load the // correct generator. int error = mbedtls_ecp_set_zero(&group->G); if (error) { throw_new_var(env, "java/security/GeneralSecurityException", err_to_string(error)); return error; } - error = mbedtls_ecp_point_read_binary(group, &group->G, point_data, data_size); + error = mbedtls_ecp_point_read_binary(group, &group->G, (unsigned char *) point_data, data_size); (*env)->ReleaseByteArrayElements(env, point_array, point_data, JNI_ABORT); if (error) { throw_new_var(env, "java/security/GeneralSecurityException", err_to_string(error)); @@ -307,7 +308,7 @@ static jobject generate_from_curve(JNIEnv *env, mbedtls_ecp_group *group) { mbedtls_ecp_point_init(&Q); if (gen_counter >= MBEDTLS_CTR_DRBG_RESEED_INTERVAL/2) { - // Reseed manually, outside of the timing window, to not disturb the timing data. + // Reseed manually, outside the timing window, to not disturb the timing data. // They are somewhat disturbed anyway, but we cannot really get rid of that easily. // We also help it by using a wrapper and pausing for random gen. mbedtls_ctr_drbg_reseed(&ctr_drbg, NULL, 0); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mscng.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mscng.c index bb27887..88e0a48 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mscng.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mscng.c @@ -1,9 +1,10 @@ +#include "c_timing.h" +#include "c_utils.h" + #include <windows.h> #include <bcrypt.h> #include "native.h" -#include "c_timing.h" -#include "c_utils.h" // BCRYPT and NT things. #define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0) diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c index d4fa0a5..dfc8389 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c @@ -1,3 +1,6 @@ +#include "c_utils.h" +#include "c_timing.h" + #include "native.h" #include <string.h> @@ -11,8 +14,6 @@ #include <fcntl.h> #include <unistd.h> -#include "c_utils.h" -#include "c_timing.h" static struct yarrow256_ctx yarrow; @@ -94,6 +95,7 @@ static const struct ecc_curve* create_curve_from_name(JNIEnv *env, const char* c if (strcasecmp("secp521r1", curve_name) == 0) { return nettle_get_secp_521r1(); } + return NULL; } static const struct ecc_curve* create_curve_from_size(JNIEnv *env, jint keysize) { diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c index 1739420..3fa560e 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c @@ -1,3 +1,6 @@ +#include "c_utils.h" +#include "c_timing.h" + #include "native.h" #include <string.h> @@ -11,9 +14,6 @@ #include <openssl/ec.h> #include <openssl/ecdsa.h> -#include "c_utils.h" -#include "c_timing.h" - static jclass provider_class; 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 4378e9b..efaa3b9 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 @@ -1,9 +1,10 @@ +#include "c_utils.h" +#include "c_timing.h" + #include "native.h" #include <stdio.h> #include <string.h> #include <tomcrypt.h> -#include "c_utils.h" -#include "c_timing.h" static prng_state ltc_prng; static jclass provider_class; 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 6e3dfed..c869233 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java @@ -77,9 +77,6 @@ public class AppTests { @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}; |
