Compiling the latest OpenSSL for Android

60,043

Solution 1

I would seriously not advise to grab anything outside of the official OpenSSL web site. You cannot take a chance when dealing with cryptography and security.

The only problem that I see is that you are using your host's gcc rather than using android's cross compilers.

Here is how I would compile the official OpenSSL on Ubuntu 14.04LTS (this works with OpenSSL 1.0.1g)

From your home folder, run the following commands:

tar xzvf ~/Downloads/openssl-1.0.1g.tar.gz
cd openssl-1.0.1g
export NDK=~/android-ndk-r9d
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=arm-linux-androideabi-4.6 --install-dir=`pwd`/android-toolchain-arm
export TOOLCHAIN_PATH=`pwd`/android-toolchain-arm/bin
export TOOL=arm-linux-androideabi
export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
export CC=$NDK_TOOLCHAIN_BASENAME-gcc
export CXX=$NDK_TOOLCHAIN_BASENAME-g++
export LINK=${CXX}
export LD=$NDK_TOOLCHAIN_BASENAME-ld
export AR=$NDK_TOOLCHAIN_BASENAME-ar
export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
export ARCH_FLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
export ARCH_LINK="-march=armv7-a -Wl,--fix-cortex-a8"
export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
export LDFLAGS=" ${ARCH_LINK} "

And then run your configure script:

./Configure android-armv7

And then build

PATH=$TOOLCHAIN_PATH:$PATH make

You should see that it is using arm-linux-androideabi-gcc instead of gcc

To build for the old armeabi:

tar xzvf ~/Downloads/openssl-1.0.1g.tar.gz
cd openssl-1.0.1g
export NDK=~/android-ndk-r9d
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=arm-linux-androideabi-4.6 --install-dir=`pwd`/android-toolchain-arm
export TOOLCHAIN_PATH=`pwd`/android-toolchain-arm/bin
export TOOL=arm-linux-androideabi
export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
export CC=$NDK_TOOLCHAIN_BASENAME-gcc
export CXX=$NDK_TOOLCHAIN_BASENAME-g++
export LINK=${CXX}
export LD=$NDK_TOOLCHAIN_BASENAME-ld
export AR=$NDK_TOOLCHAIN_BASENAME-ar
export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
export ARCH_FLAGS="-mthumb"
export ARCH_LINK=
export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
export LDFLAGS=" ${ARCH_LINK} "
./Configure android
make clean
PATH=$TOOLCHAIN_PATH:$PATH make

to build for x86 :

tar xzvf ~/Downloads/openssl-1.0.1g.tar.gz
cd openssl-1.0.1g
export NDK=~/android-ndk-r9d
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=x86-4.6 --install-dir=`pwd`/android-toolchain-x86
export TOOLCHAIN_PATH=`pwd`/android-toolchain-x86/bin
export TOOL=i686-linux-android
export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
export CC=$NDK_TOOLCHAIN_BASENAME-gcc
export CXX=$NDK_TOOLCHAIN_BASENAME-g++
export LINK=${CXX}
export LD=$NDK_TOOLCHAIN_BASENAME-ld
export AR=$NDK_TOOLCHAIN_BASENAME-ar
export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
export ARCH_FLAGS="-march=i686 -msse3 -mstackrealign -mfpmath=sse"
export ARCH_LINK=
export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
export LDFLAGS=" ${ARCH_LINK} "
./Configure android-x86
make clean
PATH=$TOOLCHAIN_PATH:$PATH make

Solution 2

In OpenSSL 1.0.1e, all I need to do is:

CC=~/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc ./Configure android-armv7
ANDROID_DEV=~/android-ndk-r9//platforms/android-8/arch-arm/usr make build_libs

Solution 3

Thanks to the instructions posted here, plus some other additions, I've made an automated script which compiles the latest OpenSSL library for Android with support for: armeabi, armeabi-v7a, x86, x86_64 and arm64-v8a:

#!/bin/bash -e
#@author Aleksandar Gotev ([email protected])
#Hints and code taken also from http://stackoverflow.com/questions/11929773/compiling-the-latest-openssl-for-android

if [ "$#" -ne 6 ]
then
    echo "Usage:"
    echo "./openssl-build <ANDROID_NDK_PATH> <OPENSSL_SOURCES_PATH> <ANDROID_TARGET_API> \\"
    echo "                <ANDROID_TARGET_ABI> <GCC_VERSION> <OUTPUT_PATH>"
    echo
    echo "Supported target ABIs: armeabi, armeabi-v7a, x86, x86_64, arm64-v8a"
    echo
    echo "Example using GCC 4.8, NDK 10e, OpenSSL 1.0.2d and Android API 21 for armeabi-v7a."
    echo "./openssl-build /home/user/android-ndk-r10e \\"
    echo "                /home/user/openssl-1.0.2d \\"
    echo "                21 \\"
    echo "                armeabi-v7a \\"
    echo "                4.8 \\"
    echo "                /home/user/output/armeabi-v7a"
    exit 1
fi

NDK_DIR=$1
OPENSSL_BASE_FOLDER=$2
OPENSSL_TARGET_API=$3
OPENSSL_TARGET_ABI=$4
OPENSSL_GCC_VERSION=$5
OPENSSL_OUTPUT_PATH=$6

NDK_MAKE_TOOLCHAIN="$NDK_DIR/build/tools/make-standalone-toolchain.sh"
OPENSSL_TMP_FOLDER="/tmp/openssl"
rm -rf "$OPENSSL_TMP_FOLDER"
mkdir -p "$OPENSSL_TMP_FOLDER"
cp -r ${OPENSSL_BASE_FOLDER} ${OPENSSL_TMP_FOLDER}

function build_library {
    mkdir -p ${OPENSSL_OUTPUT_PATH}
    export PATH=$TOOLCHAIN_PATH:$PATH
    make && make install
    rm -rf ${OPENSSL_TMP_FOLDER}
    echo "Build completed! Check output libraries in ${OPENSSL_OUTPUT_PATH}"
}

if [ "$OPENSSL_TARGET_ABI" == "armeabi-v7a" ]
then
    ${NDK_MAKE_TOOLCHAIN} --platform=android-${OPENSSL_TARGET_API} \
                          --toolchain=arm-linux-androideabi-${OPENSSL_GCC_VERSION} \
                          --install-dir="${OPENSSL_TMP_FOLDER}/android-toolchain-arm"
    export TOOLCHAIN_PATH="${OPENSSL_TMP_FOLDER}/android-toolchain-arm/bin"
    export TOOL=arm-linux-androideabi
    export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
    export CC=$NDK_TOOLCHAIN_BASENAME-gcc
    export CXX=$NDK_TOOLCHAIN_BASENAME-g++
    export LINK=${CXX}
    export LD=$NDK_TOOLCHAIN_BASENAME-ld
    export AR=$NDK_TOOLCHAIN_BASENAME-ar
    export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
    export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
    export ARCH_FLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
    export ARCH_LINK="-march=armv7-a -Wl,--fix-cortex-a8"
    export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
    export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export LDFLAGS=" ${ARCH_LINK} "
    cd ${OPENSSL_TMP_FOLDER}
    ./Configure android-armv7 --openssldir=${OPENSSL_OUTPUT_PATH}
    build_library

elif [ "$OPENSSL_TARGET_ABI" == "arm64-v8a" ]
then
    ${NDK_MAKE_TOOLCHAIN} --platform=android-${OPENSSL_TARGET_API} \
                          --toolchain=aarch64-linux-android-4.9 \
                          --install-dir="${OPENSSL_TMP_FOLDER}/android-toolchain-arm64"
    export TOOLCHAIN_PATH="${OPENSSL_TMP_FOLDER}/android-toolchain-arm64/bin"
    export TOOL=aarch64-linux-android
    export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
    export CC=$NDK_TOOLCHAIN_BASENAME-gcc
    export CXX=$NDK_TOOLCHAIN_BASENAME-g++
    export LINK=${CXX}
    export LD=$NDK_TOOLCHAIN_BASENAME-ld
    export AR=$NDK_TOOLCHAIN_BASENAME-ar
    export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
    export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
    export ARCH_FLAGS=
    export ARCH_LINK=
    export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
    export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export LDFLAGS=" ${ARCH_LINK} "
    cd ${OPENSSL_TMP_FOLDER}
    ./Configure android --openssldir=${OPENSSL_OUTPUT_PATH}
    build_library

elif [ "$OPENSSL_TARGET_ABI" == "armeabi" ]
then
    ${NDK_MAKE_TOOLCHAIN} --platform=android-${OPENSSL_TARGET_API} \
                          --toolchain=arm-linux-androideabi-${OPENSSL_GCC_VERSION} \
                          --install-dir="${OPENSSL_TMP_FOLDER}/android-toolchain-arm"
    export TOOLCHAIN_PATH="${OPENSSL_TMP_FOLDER}/android-toolchain-arm/bin"
    export TOOL=arm-linux-androideabi
    export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
    export CC=$NDK_TOOLCHAIN_BASENAME-gcc
    export CXX=$NDK_TOOLCHAIN_BASENAME-g++
    export LINK=${CXX}
    export LD=$NDK_TOOLCHAIN_BASENAME-ld
    export AR=$NDK_TOOLCHAIN_BASENAME-ar
    export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
    export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
    export ARCH_FLAGS="-mthumb"
    export ARCH_LINK=
    export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
    export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export LDFLAGS=" ${ARCH_LINK} "
    cd ${OPENSSL_TMP_FOLDER}
    ./Configure android --openssldir=${OPENSSL_OUTPUT_PATH}
    build_library

elif [ "$OPENSSL_TARGET_ABI" == "x86" ]
then
    ${NDK_MAKE_TOOLCHAIN} --platform=android-${OPENSSL_TARGET_API} \
                          --toolchain=x86-${OPENSSL_GCC_VERSION} \
                          --install-dir="${OPENSSL_TMP_FOLDER}/android-toolchain-x86"
    export TOOLCHAIN_PATH="${OPENSSL_TMP_FOLDER}/android-toolchain-x86/bin"
    export TOOL=i686-linux-android
    export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
    export CC=$NDK_TOOLCHAIN_BASENAME-gcc
    export CXX=$NDK_TOOLCHAIN_BASENAME-g++
    export LINK=${CXX}
    export LD=$NDK_TOOLCHAIN_BASENAME-ld
    export AR=$NDK_TOOLCHAIN_BASENAME-ar
    export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
    export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
    export ARCH_FLAGS="-march=i686 -msse3 -mstackrealign -mfpmath=sse"
    export ARCH_LINK=
    export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
    export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export LDFLAGS=" ${ARCH_LINK} "
    cd ${OPENSSL_TMP_FOLDER}
    ./Configure android-x86 --openssldir=${OPENSSL_OUTPUT_PATH}
    build_library

elif [ "$OPENSSL_TARGET_ABI" == "x86_64" ]
then
    ${NDK_MAKE_TOOLCHAIN} --platform=android-${OPENSSL_TARGET_API} \
                          --toolchain=x86_64-4.9 \
                          --install-dir="${OPENSSL_TMP_FOLDER}/android-toolchain-x86_64"
    export TOOLCHAIN_PATH="${OPENSSL_TMP_FOLDER}/android-toolchain-x86_64/bin"
    export TOOL=x86_64-linux-android
    export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL}
    export CC=$NDK_TOOLCHAIN_BASENAME-gcc
    export CXX=$NDK_TOOLCHAIN_BASENAME-g++
    export LINK=${CXX}
    export LD=$NDK_TOOLCHAIN_BASENAME-ld
    export AR=$NDK_TOOLCHAIN_BASENAME-ar
    export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib
    export STRIP=$NDK_TOOLCHAIN_BASENAME-strip
    export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions "
    export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 "
    export LDFLAGS=" ${ARCH_LINK} "
    cd ${OPENSSL_TMP_FOLDER}
    ./Configure linux-x86_64 --openssldir=${OPENSSL_OUTPUT_PATH}
    build_library

else
    echo "Unsupported target ABI: $OPENSSL_TARGET_ABI"
    exit 1
fi

Script docs: https://github.com/alexbbb/pjsip-android-builder#build-only-openssl

For the last version check: https://github.com/alexbbb/pjsip-android-builder/blob/master/openssl-build

Solution 4

I glued together some useful advices here to a build environment for OpenSSL for Android which works for me.

  • Supports build for multiple architectures - ARM, ARMv7, X86
  • Uses OpenSSL source codes
  • Integrated with Android.mk build
  • Contains pre-compiled OpenSSL 1.0.2h (use if you want or compile your own)

https://github.com/ph4r05/android-openssl

Solution 5

In case someone encounters the problem of using vulnerable version of OpenSSL (< 1.0.2f/1.0.1r) in one of the native libraries, I add some more details and instructions.

Preconditions: Android NDK need to be configured first.

  1. First of all, download the OpenSSL compatible version (> 1.0.2f/1.0.1r).
  2. Download two scripts from this link. In case someone wonders what they do (and you should - it is a cryptographic library!!!): They build the OpenSSL library for every android ABI processor architecture (armeabi, x86, mips, etc...)

  3. Modify setenv-android-mod.sh -> line 18 with the ndk version

  4. Modify setenv-android-mod.sh -> line 40 with the Android API version

  5. Modify build-all-arch.sh -> line 7 with the folder name of the OpenSSL library (in my case it was openssl-1.0.1t)

  6. After successful build, inside the folder dist the libraries will be present

To add the openSSL to project as prebuilt static libraries, create:

  1. openssl folder under jni directory containing lib/ (which contain the .a files for the supported architectures),
  2. include/ which has the necessary includes (you can find that under the openssl version you downloaded, be aware that some of the header files are symbolic links)
  3. Modify Android.mk inside jni folder adding the following:

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libssl
    LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libssl.a
    include $(PREBUILT_STATIC_LIBRARY)
    include $(CLEAR_VARS)
    LOCAL_MODULE := libcrypto
    LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libcrypto.a
    include $(PREBUILT_STATIC_LIBRARY)
    

Then, to use the library within another jni module add the following to it's Android.mk file:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../openssl/include
LOCAL_STATIC_LIBRARIES := libssl libcrypto
Share:
60,043
Suman
Author by

Suman

Updated on March 24, 2021

Comments

  • Suman
    Suman about 3 years

    I am trying to generate the shared library for the (.so) files of the OpenSSL1.0.1c for the Android. I found that they have added three options for compiling for the Android in the android script.

    ./Configure android-armv7  (or)
    ./Configure android-x86    (or)
    ./Configure android
    

    once I configured for the OS and then try to compile, its throwing errors. Currently I am working x86 windows7 and installed Cygwin, Android sdk R20, Android NDK r8

    sh-4.1$ make
    making all in crypto...
    make[1]: Entering directory `/cygdrive/d/SourceCodes/OpenSSL/openssl-1.0.1c/crypto'
    gcc -I. -I.. -I../include  -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -march=armv7-a -mandroid -I/include -B/lib -O3 -fomit-frame-pointer -Wall -DOPENSSL_BN_ASM_MONT -DOP
    ENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DGHASH_ASM   -c -o cryptlib.o cryptlib.c
    cc1: error: unrecognized command line option "-mandroid"
    cryptlib.c:1:0: error: bad value (armv7-a) for -march= switch
    <builtin>: recipe for target `cryptlib.o' failed
    make[1]: *** [cryptlib.o] Error 1
    make[1]: Leaving directory `/cygdrive/d/SourceCodes/OpenSSL/openssl-1.0.1c/crypto'
    Makefile:278: recipe for target `build_crypto' failed
    make: *** [build_crypto] Error 1
    sh-4.1$
    

    Please let me know if anyone faced the similar issue and got the solution for resolving the same.