1

I am using OpenSSL in my project.library is detecting but getting some errors like below:

Error:(23) undefined reference to 'RSA_generate_key'
Error:(44) undefined reference to 'AES_set_encrypt_key'
Error:(45) undefined reference to 'AES_encrypt'
Error:(49) undefined reference to 'AES_set_decrypt_key'
Error:(50) undefined reference to 'AES_decrypt'
Error:error: linker command failed with exit code 1 (use -v to see invocation)

my simple cpp code is here

native-lib.cpp

#include<jni.h>
#include <string>

#include <android/log.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>


extern "C"
JNIEXPORT jstring  JNICALL
Java_com_manvish_bwssb_Activities_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
#define nr_bits 2048

extern "C"
JNIEXPORT int JNICALL
  Java_com_manvish_bwssb_Activities_MainActivity_checkRSA(JNIEnv *env, jobject /* this */) {
    RSA *rsa = RSA_generate_key(nr_bits, 65537, NULL, NULL);
    return 0;
}

static const unsigned char key[] = {
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};

extern "C"
void
Java_com_manvish_bwssb_Activities_MainActivity_checkAES(JNIEnv *env, jobject /* this */) {

    unsigned char text[] = "Kishan of Nanda";
    unsigned char out[80];
    unsigned char decout[80];

    AES_KEY wctx;

    AES_set_encrypt_key(key, 128, &wctx);
    AES_encrypt(text, out, &wctx);
    printf("encryp data = %s\n", out);
    __android_log_print(ANDROID_LOG_DEBUG, "Gajanand", "Encrypted data: %s\n", out);

    AES_set_decrypt_key(key, 128, &wctx);
    AES_decrypt(out, decout, &wctx);

    printf(" Decrypted o/p: %s \n", decout);
    __android_log_print(ANDROID_LOG_DEBUG, "Gajanand", "Decrypted data: %s\n", decout);
}

and my Android.mk file is here

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := myLibrary
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_C_INCLUDES = $(LOCAL_PATH)/include
LOCAL_SRC_FILES +:= libcrypto.so
LOCAL_SRC_FILES +:= libssl.so
LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

I included appropriate .so files in appropriate folder. I am not getting reason behind the undefined reference error.please help me to solve this issue.

jww
  • 97,681
  • 90
  • 411
  • 885
Gaju Kollur
  • 2,046
  • 5
  • 23
  • 47
  • An so file isn't source; it's a library; you need to add -l like you did with log – UKMonkey Jan 29 '18 at 13:07
  • @UKMonkey I am not getting ..can u write code by seeing above question .? – Gaju Kollur Jan 29 '18 at 13:10
  • Have you built OpenSSL for Android using the NDK toolchain? Although OpenSSL is on the Android platform (and used by Android system components) it is not part of the NDK and you need to build it yourself. – Richard Critten Jan 29 '18 at 13:33
  • @RichardCritten No i haven't built .. i am using preBuilt openssl – Gaju Kollur Jan 29 '18 at 13:34
  • Then @UKMonkey answer is correct you need to add the prebuilt directory to your library path as well. – Richard Critten Jan 29 '18 at 13:36
  • @RichardCritten I thought that; apart from on the [android site](https://developer.android.com/ndk/guides/prebuilts.html) they have this as an example `LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so` which I rank somewhere on the list of "wtf" moments – UKMonkey Jan 29 '18 at 14:50
  • 1
    You should *not* use `AES_encrypt` and friends. That's a software-only implementation, so you will not enjoy hardware support, like AES-NI. You should be using `EVP_*` functions. See [EVP Symmetric Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption) on the OpenSSL wiki. In fact, you should probably be using authenticated encryption because it provides *both* confidentiality and authenticity. See [EVP Authenticated Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption) on the OpenSSL wiki. – jww Jan 29 '18 at 15:05
  • 1
    Also see [use libcryto.so and libssl.so in an android project?](https://stackoverflow.com/q/22531390/608639). – jww Jan 29 '18 at 16:56
  • 1
    @RichardCritten "*OpenSSL is ... used by Android system components*" - not anymore, as of Android 6. Now it uses BoringSSL, which is a custom minimalized fork of OpenSSL that makes a lot of drastic changes and removals from the OpenSSL API. – Remy Lebeau Jan 29 '18 at 17:10
  • @RemyLebeau Thanks must admit my Android knowledge is a bit out of date. Was just trying to remind the OP that linking to internal components is not supported. – Richard Critten Jan 29 '18 at 18:08
  • 1
    @RichardCritten, you are both right. While Android switched to BoringSSL, its shared libraries are still named **libcrypto** and **libssl**. But for Android 7 and up, even **dlopen()** will refuse to use them for a non-system app (see [developers blog](https://android-developers.googleblog.com/2016/06/android-changes-for-ndk-developers.html)). – Alex Cohn Jan 29 '18 at 22:23
  • @RemyLebeau, sorry [the comment](https://stackoverflow.com/questions/48501891/linking-errors-in-openssl-library#comment84016855_48501891) could not @‎mention two people. – Alex Cohn Jan 29 '18 at 22:25
  • @AlexCohn: "*its shared libraries are still named **libcrypto** and **libssl***" - yup, which causes problems for projects that think they are loading OpenSSL and not BoringSSL, and then fail when they can't find what BoringSSL has removed from OpenSSL – Remy Lebeau Jan 29 '18 at 23:51

1 Answers1

3

Your problem stems from these lines in your makefile

LOCAL_SRC_FILES +:= libcrypto.so
LOCAL_SRC_FILES +:= libssl.so

Source (SRC for short) files are used by the compiler; which will generate .a files. .so files and .a files are used by the linker to generate executables and .so files.

I would suggest removing those 2 lines and then adding

LOCAL_LDLIBS := -llog -lssl -lcrypto

Edit: Seems to not be the complete solution; but leaving here for posterity.

UKMonkey
  • 6,941
  • 3
  • 21
  • 30
  • after adding above line getting error like this Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lssl – Gaju Kollur Jan 29 '18 at 13:23
  • @ArjunParth - Now fix your paths. Also see [How to specify path of libraries in Android.mk file or Application.mk file?](https://stackoverflow.com/q/6475944/608639) – jww Jan 29 '18 at 15:07
  • 2
    Only NDK public libraries may appear in `LOCAL_LDLIBS`, e.g. `-llog`, `-ldl`, etc. For user libraries, you cannot use this approach anymore (deprecated at NDK r12 IIRC). These libraries should be declared as PREBUILT_SHARED, as [in this answer](https://stackoverflow.com/a/22538989/192373) – Alex Cohn Jan 29 '18 at 22:07
  • @AlexCohn i used above link it solved linkage problem but again app is giving some error like this [Error Link](https://stackoverflow.com/questions/48515132/java-lang-unsatisfiedlinkerror-dlopen-failed-could-not-load-library-libcrypto) – Gaju Kollur Jan 30 '18 at 06:45