/** * Note: * This procedure directly writes the internal representation of BIGNUMs. * We do so as there is no direct interface based on Little Endian Integer Arrays. * Also note that the same representation is used in the Cordoba Java Implementation of BigIntegers, * whereof certain functionality is still being used. */ extern "C" void Java_java_math_NativeBN_litEndInts2bn(JNIEnv* env, jclass, jintArray arr, int len, jboolean neg, jlong ret0) { if (!oneValidHandle(env, ret0)) return; BIGNUM* ret = toBigNum(ret0); bn_check_top(ret); if (len > 0) { ScopedIntArrayRO scopedArray(env, arr); if (scopedArray.get() == NULL) { return; } STATIC_ASSERT(sizeof(BN_ULONG) == sizeof(jint), BN_ULONG_not_32_bit); const BN_ULONG* tmpInts = reinterpret_cast<const BN_ULONG*>(scopedArray.get()); if ((tmpInts != NULL) && (bn_wexpand(ret, len) != NULL)) { int i = len; do { i--; ret->d[i] = tmpInts[i]; } while (i > 0); ret->top = len; ret->neg = neg; // need to call this due to clear byte at top if avoiding // having the top bit set (-ve number) // Basically get rid of top zero ints: bn_correct_top(ret); } else { throwExceptionIfNecessary(env); } } else { // (len = 0) means value = 0 and sign will be 0, too. ret->top = 0; } }
extern "C" void Java_java_math_NativeBN_BN_1generate_1prime_1ex(JNIEnv* env, jclass, jlong ret, int bits, jboolean safe, jlong add, jlong rem, jlong cb) { if (!oneValidHandle(env, ret)) return; BN_generate_prime_ex(toBigNum(ret), bits, safe, toBigNum(add), toBigNum(rem), reinterpret_cast<BN_GENCB*>(cb)); throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_BN_1shift(JNIEnv* env, jclass, jlong r, jlong a, int n) { if (!twoValidHandles(env, r, a)) return; if (n >= 0) { BN_lshift(toBigNum(r), toBigNum(a), n); } else { BN_rshift(toBigNum(r), toBigNum(a), -n); } throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_BN_1bin2bn(JNIEnv* env, jclass, jbyteArray arr, int len, jboolean neg, jlong ret) { if (!oneValidHandle(env, ret)) return; ScopedByteArrayRO bytes(env, arr); if (bytes.get() == NULL) { return; } BN_bin2bn(reinterpret_cast<const unsigned char*>(bytes.get()), len, toBigNum(ret)); if (!throwExceptionIfNecessary(env) && neg) { BN_set_negative(toBigNum(ret), true); } }
extern "C" int Java_java_math_NativeBN_BN_1hex2bn(JNIEnv* env, jclass, jlong a0, jstring str) { if (!oneValidHandle(env, a0)) return -1; ScopedUtfChars chars(env, str); if (chars.c_str() == NULL) { return -1; } BIGNUM* a = toBigNum(a0); int result = BN_hex2bn(&a, chars.c_str()); throwExceptionIfNecessary(env); return result; }
/* * public static native void EVP_VerifyUpdate(int, byte[], int, int) */ static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length) { // LOGI("NativeCrypto_EVP_VerifyUpdate %x, %x, %d, %d", ctx, buffer, offset, length); if (ctx == NULL || buffer == NULL) { throwNullPointerException(env); return; } jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL); EVP_VerifyUpdate(ctx, (unsigned char*) (bufferBytes + offset), length); env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT); throwExceptionIfNecessary(env); }
/* * public static native void EVP_DigestReset(int) */ static jint NativeCrypto_EVP_DigestBlockSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) { // LOGI("NativeCrypto_EVP_DigestBlockSize"); if (ctx == NULL) { throwNullPointerException(env); return -1; } int result = EVP_MD_CTX_block_size(ctx); throwExceptionIfNecessary(env); return result; }
/* * public static native void EVP_VerifyFinal(int, byte[], int, int, int) */ static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length, EVP_PKEY* pkey) { // LOGI("NativeCrypto_EVP_VerifyFinal %x, %x, %d, %d %x", ctx, buffer, offset, length, pkey); if (ctx == NULL || buffer == NULL || pkey == NULL) { throwNullPointerException(env); return -1; } jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL); int result = EVP_VerifyFinal(ctx, (unsigned char*) (bufferBytes + offset), length, pkey); env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT); throwExceptionIfNecessary(env); return result; }
/* * public static native int EVP_DigestFinal(int, byte[], int) */ static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray hash, jint offset) { // LOGI("NativeCrypto_EVP_DigestFinal%x, %x, %d, %d", ctx, hash, offset); if (ctx == NULL || hash == NULL) { throwNullPointerException(env); return -1; } int result = -1; jbyte* hashBytes = env->GetByteArrayElements(hash, NULL); EVP_DigestFinal(ctx, (unsigned char*) (hashBytes + offset), (unsigned int*)&result); env->ReleaseByteArrayElements(hash, hashBytes, 0); throwExceptionIfNecessary(env); return result; }
extern "C" void Java_java_math_NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, unsigned long long dw, jboolean neg) { if (!oneValidHandle(env, a0)) return; unsigned int hi = dw >> 32; // This shifts without sign extension. int lo = (int)dw; // This truncates implicitly. // cf. litEndInts2bn: BIGNUM* a = toBigNum(a0); bn_check_top(a); if (bn_wexpand(a, 2) != NULL) { a->d[0] = lo; a->d[1] = hi; a->top = 2; a->neg = neg; bn_correct_top(a); } else { throwExceptionIfNecessary(env); } }
/* * public static native void EVP_VerifyInit(int, java.lang.String) */ static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) { // LOGI("NativeCrypto_EVP_VerifyInit"); if (ctx == NULL || algorithm == NULL) { throwNullPointerException(env); return; } const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL); const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars)); env->ReleaseStringUTFChars(algorithm, algorithmChars); if (digest == NULL) { throwRuntimeException(env, "Hash algorithm not found"); return; } EVP_VerifyInit(ctx, digest); throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_twosComp2bn(JNIEnv* env, jclass cls, jbyteArray arr, int bytesLen, jlong ret0) { if (!oneValidHandle(env, ret0)) return; BIGNUM* ret = toBigNum(ret0); ScopedByteArrayRO bytes(env, arr); if (bytes.get() == NULL) { return; } const unsigned char* s = reinterpret_cast<const unsigned char*>(bytes.get()); if ((bytes[0] & 0X80) == 0) { // Positive value! // // We can use the existing BN implementation for unsigned big endian bytes: // BN_bin2bn(s, bytesLen, ret); BN_set_negative(ret, false); } else { // Negative value! // // We need to apply two's complement: // negBigEndianBytes2bn(env, cls, s, bytesLen, ret0); BN_set_negative(ret, true); } throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_BN_1sub(JNIEnv* env, jclass, jlong r, jlong a, jlong b) { if (!threeValidHandles(env, r, a, b)) return; BN_sub(toBigNum(r), toBigNum(a), toBigNum(b)); throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_BN_1mul_1word(JNIEnv* env, jclass, jlong a, BN_ULONG w) { if (!oneValidHandle(env, a)) return; BN_mul_word(toBigNum(a), w); throwExceptionIfNecessary(env); }
extern "C" BN_ULONG Java_java_math_NativeBN_BN_1mod_1word(JNIEnv* env, jclass, jlong a, BN_ULONG w) { if (!oneValidHandle(env, a)) return 0; int result = BN_mod_word(toBigNum(a), w); throwExceptionIfNecessary(env); return result; }
extern "C" void Java_java_math_NativeBN_BN_1mod_1inverse(JNIEnv* env, jclass, jlong ret, jlong a, jlong n) { if (!threeValidHandles(env, ret, a, n)) return; Unique_BN_CTX ctx(BN_CTX_new()); BN_mod_inverse(toBigNum(ret), toBigNum(a), toBigNum(n), ctx.get()); throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_BN_1mod_1exp(JNIEnv* env, jclass, jlong r, jlong a, jlong p, jlong m) { if (!fourValidHandles(env, r, a, p, m)) return; Unique_BN_CTX ctx(BN_CTX_new()); BN_mod_exp(toBigNum(r), toBigNum(a), toBigNum(p), toBigNum(m), ctx.get()); throwExceptionIfNecessary(env); }
static void NativeBN_BN_copy(JNIEnv* env, jclass, jlong to, jlong from) { if (!twoValidHandles(env, to, from)) return; BN_copy(toBigNum(to), toBigNum(from)); throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_BN_1mul(JNIEnv* env, jclass, jlong r, jlong a, jlong b) { if (!threeValidHandles(env, r, a, b)) return; Unique_BN_CTX ctx(BN_CTX_new()); BN_mul(toBigNum(r), toBigNum(a), toBigNum(b), ctx.get()); throwExceptionIfNecessary(env); }
extern "C" void Java_java_math_NativeBN_BN_1div(JNIEnv* env, jclass, jlong dv, jlong rem, jlong m, jlong d) { if (!fourValidHandles(env, (rem ? rem : dv), (dv ? dv : rem), m, d)) return; Unique_BN_CTX ctx(BN_CTX_new()); BN_div(toBigNum(dv), toBigNum(rem), toBigNum(m), toBigNum(d), ctx.get()); throwExceptionIfNecessary(env); }
static jlong NativeBN_BN_new(JNIEnv* env, jclass) { jlong result = static_cast<jlong>(reinterpret_cast<uintptr_t>(BN_new())); throwExceptionIfNecessary(env); return result; }
extern "C" void Java_java_math_NativeBN_BN_1copy(JNIEnv* env, jclass, jlong to, jlong from) { if (!twoValidHandles(env, to, from)) return; BN_copy(toBigNum(to), toBigNum(from)); throwExceptionIfNecessary(env); }