I am trying to build the latest OpenSSL for Android following Compiling the latest OpenSSL for Android. I manage to build the static libs.
However I try to compile the shared libs. To do so I run:
./Configure android-armv7 shared
This compiles. Problem is that this creates a versioned lib like libssl.so.1.0.0, which is not supported by Android. Just rename does not do because of SONAME is still pointing to the versioned filename.
Different problem I have is when trying to the create the libs for old armeabi platform. When I run:
./Configure android shared
it creates the static libs for the old armeabi plattform, the shared libs however are arm-v7 architecture.
How to build OpenSSL as unversioned shared lib (for Android)?
There's a lot to it because its a cross compile. You should probably start here (its the OpenSSL wiki): OpenSSL and Android.
However I try to compile the shared libs. To do so I run:
./Configure android-armv7 shared
Ok, so you are missing a few things. At minimum, you should be using the Android NDK. This is a requirement from AOSP. I've seen a number of little problems over the years due to using non-NDK tools.
And I believe you need the following environmental variables set. This is an OpenSSL requirement.
x86:
export MACHINE=i686
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=x86
export CROSS_COMPILE="i686-linux-android-"
ARM:
export MACHINE=armv7
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=arm
Both:
export ANDROID_DEV="$ANDROID_NDK_ROOT/platforms/$_ANDROID_API/$_ANDROID_ARCH/usr"
export HOSTCC=gcc
ANDROID_DEV
will evaluate to something like /opt/android-ndk-r9/platforms/android-14/arch-arm/usr
.
You need to provide the output of compiling at least one file. But I expect you are missing --sysroot
too. The argument to --sysroot
will be something like /opt/android-ndk-r9/platforms/android-14/arch-arm
.
I would recommend following the instructions at OpenSSL and Android. The first thing the instructions tell you to do is run setenv-android.sh
to set the proper variables.
Here's what my run looks like using OpenSSL and Android.
$ cd openssl-1.0.1h
$ . ./setenv-android.sh
Error: FIPS_SIG does not specify incore module. Please edit this script.
ANDROID_NDK_ROOT: /opt/android-ndk-r9
ANDROID_EABI: arm-linux-androideabi-4.6
ANDROID_API: android-14
ANDROID_SYSROOT: /opt/android-ndk-r9/platforms/android-14/arch-arm
ANDROID_TOOLCHAIN: /opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin
FIPS_SIG:
CROSS_COMPILE: arm-linux-androideabi-
ANDROID_DEV: /opt/android-ndk-r9/platforms/android-14/arch-arm/usr
$ ./config shared no-ssl2 no-ssl3 no-comp no-engines no-hw no-psk no-srp
Operating system: armv7-whatever-android
Configuring for android-armv7
Configuring for android-armv7
no-comp [option] OPENSSL_NO_COMP (skip dir)
no-ec_nistp_64_gcc_128 [default] OPENSSL_NO_EC_NISTP_64_GCC_128 (skip dir)
no-engines [option] OPENSSL_NO_ENGINES (skip dir)
...
no-srp [option] OPENSSL_NO_SRP (skip dir)
no-ssl2 [option] OPENSSL_NO_SSL2 (skip dir)
no-ssl3 [option] OPENSSL_NO_SSL3 (skip dir)
no-store [experimental] OPENSSL_NO_STORE (skip dir)
no-zlib [default]
no-zlib-dynamic [default]
IsMK1MF=0
CC =gcc
...
$ make
...
arm-linux-androideabi-gcc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS
-D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -march=armv7-a -mandroid
-mfloat-abi=softfp -I/opt/android-ndk-r9/platforms/android-14/arch-arm/usr/include
-B/opt/android-ndk-r9/platforms/android-14/arch-arm/usr/lib -Os -fomit-frame-pointer
-Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM
-DAES_ASM -DGHASH_ASM -c -o cryptlib.o cryptlib.c
...
You can ignore Error: FIPS_SIG does not specify incore module...
because you are not building a FIPS Capable library.
... unversioned shared lib (for Android)?
This will probably get you in trouble. I believe the way to do it is to provide a wrapper around the static lib, and use your wrapper as a surrogate. So you never use the OpenSSL shared object, and versioning does not matter.
The problem is your process will fork from Zygote. Zygote already has OpenSSL 0.9.8 mapped into its space. So when Zygote forks for your process, your process will already have 0.9.8 and the shared object in your APK will not be mapped in. You will simply use the existing OpenSSL. That will lead to obscure problems.
I also believe there are bugs in OpenSSL's Configure
. First, the configuration is missing -mfloat-abi=softfp
. That's an AOSP requirement. Second, -O3
is used rather than -Os
. That's a mobile requirement on resource constrained devices.
You might want to open Makefile
and make the changes after you configure. I do the same before I build the library.
As to build a version-less libcrypto
, overwriting CALC_VERSIONS
does the trick (at least for 1.0.2d):
make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" all
Then, the sub-target link-shared
of the target install_sw
must be disabled (otherwise broken symlinks overwrite the libraries), which can be done by creating a dummy file of the same name at the suitable place (furthermore, SHLIB_EXT must also be set for the version-less files to be copied).
The complete bash-script I used:
ORIG_PATH=$PATH
SCRIPT_PATH=$(dirname $(readlink -f $0))
tar -zxf $SCRIPT_PATH/openssl-fips-2.0.10.tar.gz
tar -zxf $SCRIPT_PATH/openssl-1.0.2d.tar.gz
ANDROID_NDK_PATH=<system-specific-path>/android-ndk-r10e-linux
ANDROID_API=android-14
ANDROID_SYSROOT=$ANDROID_NDK_PATH/platforms/$ANDROID_API/arch-arm
export OPENSSLDIR=$SCRIPT_PATH/ssl/android/arm
export FIPSDIR=$OPENSSLDIR/fips-2.0
export HOSTCC=gcc
export FIPS_SIG=$SCRIPT_PATH/openssl-fips-2.0.10/util/incore
export ANDROID_DEV=$ANDROID_SYSROOT/usr
export PATH=$ANDROID_NDK_PATH/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ORIG_PATH
export MACHINE=armv7
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=arm
export CROSS_COMPILE=arm-linux-androideabi-
cd $SCRIPT_PATH/openssl-fips-2.0.10
./config shared
make clean
make
make install_sw
cd $SCRIPT_PATH/openssl-1.0.2d
./config fips shared -no-sslv2 -no-sslv3 -no-comp -no-hw -no-engines --openssldir=$OPENSSLDIR --with-fipsdir=$FIPSDIR --with-fipslibdir=$FIPSDIR/lib/
make clean
make depend
make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" MAKE="make -e" all
mkdir -p $OPENSSLDIR/lib
echo "place-holder make target for avoiding symlinks" >> $OPENSSLDIR/lib/link-shared
make SHLIB_EXT=.so install_sw
rm $OPENSSLDIR/lib/link-shared
Then no generated object file should have or reference a versioned so-name:
$ readelf -d ssl/android/arm/lib/libcrypto.so | grep 'SONAME\|NEEDED'
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x0000000e (SONAME) Library soname: [libcrypto.so]
$ readelf -d ssl/android/arm/lib/libssl.so | grep 'SONAME\|NEEDED'
0x00000001 (NEEDED) Shared library: [libcrypto.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x0000000e (SONAME) Library soname: [libssl.so]
$ readelf -d ssl/android/arm/bin/openssl | grep 'SONAME\|NEEDED'
0x00000001 (NEEDED) Shared library: [libssl.so]
0x00000001 (NEEDED) Shared library: [libcrypto.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With