Frage

I am trying to write a wrapper for encryption/decryption file for Android using OpenSSL open source library. So I created a NDK Android project to compile library OpenSSL using NDK.

Here is project structure:

Android Project
    src
    jni
        openssl-1.0.1e     (folder contains openssl source code)
            crypto         (folder contains crypto source code)
                Android.mk (the Android makefile to define STATIC_LIBRARY)

            include
                openssl    (folder contains header files)

        wrapper            (folder contains wrapper source code, my implementation here)
            aes_wrapper.c  (my wrapper implementation)
            Android.mk     (the Android makefile to define SHARED_LIBRARY)

        Android.mk         (the Android makefile that calls all sub android makefiles)
        Application.mk     (the Application makefile, I use to define APP_ABI)

Here is content of Android.mk in folder jni/openssl-1.0.1e/crypto

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_C_INCLUDES := \
    $(NDK_PROJECT_PATH) \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto/asn1 \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto/aes \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto/evp \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/include \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/include/openssl

LOCAL_SRC_FILES := all source files here

LOCAL_MODULE    := crypto

include $(BUILD_STATIC_LIBRARY)

Here is content of Android.mk in folder jni/wrapper

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_C_INCLUDES := \
    $(NDK_PROJECT_PATH) \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto/asn1 \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto/aes \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/crypto/evp \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/include \
    $(NDK_PROJECT_PATH)/jni/openssl-1.0.1e/include/openssl

LOCAL_SRC_FILES := aes_wrapper.c

LOCAL_STATIC_LIBRARIES += crypto

LOCAL_MODULE    := aes_wrapper

include $(BUILD_SHARED_LIBRARY)

Here is content of Android.mk in folder jni

include $(call all-subdir-makefiles)

Here is content of Application.mk in folder jni

APP_ABI := all

When I call ndk-build I got some "undefined reference to" errors. I have been trying to fix a couple of days but unfortunately I was not successful. Could anyone help me? Any help will be appreciated.

EDIT: I got bunch of errors like this

/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe:
./obj/local/armeabi-v7a/objs/aes_wrapper/aes_wrapper.o: in function encrypt:jni/wrapper/aes_wrapper.c:21: error: undefined reference to 'AES_encrypt'
War es hilfreich?

Lösung

When I call ndk-build I got some "undefined reference to" errors. I have been trying to fix a couple of days but unfortunately I was not successful.

It sounds like AES_encrypt is not you only error. For AES_encrypt, here's where its located:

$ grep -R AES_encrypt *
crypto/aes/aes.h:void AES_encrypt(const unsigned char *in, unsigned char *out,
...
crypto/aes/aes_core.c:void AES_encrypt(const unsigned char *in, unsigned char *out,
...

I don't use the NDK build system, so I'm not sure if aes_core.c is actually being compiled from your example.

However, you do have LOCAL_STATIC_LIBRARIES += crypto, and you can verify the function is present in the archive with the NDK's version of nm (I believe its arm-linux-androideabi-nm) as follows. You want to see an entry with a T (T is a definition in the Text section):

$ nm libcrypto.a | grep -i AES_encrypt
...
                 U AES_encrypt
0000000000000460 T AES_encrypt
0000000000000000 t _x86_64_AES_encrypt
00000000000001f0 t _x86_64_AES_encrypt_compact
...

If you are still having trouble, OpenSSL offers direction for building the library from the command line outside of the NDK build system. See FIPS Library and Android (and skip the FIPS part). From Build the FIPS Capable Library:

# From the 'root' directory
$ . ./setenv-android.sh
$ cd openssl-1.0.1e/

$ ./config shared no-ssl2 no-comp no-hw no-engine \
    --openssldir=/usr/local/ssl/$ANDROID_API

$ make depend
$ make all
$ sudo -E make install \
    CC=$ANDROID_TOOLCHAIN/arm-linux-androideabi-gcc \
    RANLIB=$ANDROID_TOOLCHAIN/arm-linux-androideabi-ranlib

In the recipe above, ANDROID_TOOLCHAIN is set by the setenv-android.sh script.

Also, you can usually find something prebuilt on Github. http://www.google.com/search?q=openssl+android+site:github.com

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top