Why is opensslconf.h different for each architecture?
opensslconf.h
holds platform specific configuration and installation information. As you noted, an example of platform configuration data is RC4_INT
.
Other examples of platform configuration information include the defines OPENSSL_NO_SSL2
if ./Configure no-ssl2
; and OPENSSL_NO_SSL3
if ./Configure no-ssl3
. Examples of installation information are the OPENSSLDIR
, which holds the location of OpenSSL's configuration file openssl.conf
(among other location information)
The last examples, no-ssl2
, no-ssl3
and OPENSSLDIR
, are specified by the user. They are not fixed for a platform.
(A related question pertains the usefulness of OPENSSLDIR
in sandboxes and walled gardens, but I've never seen an answer to it. Also see CONF-less OpenSSL configuration? on the OpenSSL mailing list).
Unfortunately, contents of the OpenSSL #include directory are different per architecture, per platform... Upon closer examination, the only file that's common but different across all platforms & architectures is "opensslconf.h".
That's not exactly correct. bn.h
is different, too.
I would like to have only ONE set of OpenSSL #includes that applies to all architectures & platforms... My first question is if it's possible to have just one OpenSSL #include directory as I'd like? If so, which version of "opensslconf.h" should I choose, and how do I know it will work?
Yes, its possible to have only one opensslconf.h
and only one bh.h
. But you will have to build it by hand, and it will work if you diligently guard the defines of interest and transcribe them without error. You cannot choose one and expect it to work for all architectures and platforms.
I've used the following technique to combine them on OS X and iOS for fat libraries. The steps are detailed at Build Multiarch OpenSSL on OS X, but I'm guessing you know what's going on by looking at it.
$ cat $HOME/ssl/include/openssl/opensslconf.h
#ifndef OPENSSL_MULTIARCH_CONF_HEADER
#define OPENSSL_MULTIARCH_CONF_HEADER
#if __i386 || __i386__
# include "opensslconf-x86.h"
#elif __x86_64 || __x86_64__ || __amd64 || __amd64__
# include "opensslconf-x64.h"
#else
# error Unknown architecture
#endif
#endif /* OPENSSL_MULTIARCH_CONF_HEADER */
and:
$ cat $HOME/ssl/include/openssl/bn.h
#ifndef OPENSSL_MULTIARCH_BN_HEADER
#define OPENSSL_MULTIARCH_BN_HEADER
#if __i386 || __i386__
# include "bn-x86.h"
#elif __x86_64 || __x86_64__ || __amd64 || __amd64__
# include "bn-x64.h"
#else
# error Unknown architecture
#endif
#endif /* OPENSSL_MULTIARCH_BN_HEADER */
My second question is why this is an issue AT ALL. Why can't these platform differences be encapsulated by OpenSSL? Isn't it already keeping track of many other variables and types that change as you build for different architectures?
I've never seen a definitive answer on the subject. Maybe you should ask on one of the OpenSSL mailing lists, like openssl-dev.
My guess is, there's too many platforms and configuration options to stuff them all in one opensslconf.h
(and one bn.h
). Here's the short list of built-in targets. wc -l
tells us there are 144 of them.
The list does not include the various configuration options, like enable-ec_nistp_64_gcc_128
for certain processors (it has nothing to do with NIST or FIPS). Also see Compilation and Installation | Configure Options on the OpenSSL wiki.
$ ./Configure LIST
Configuring OpenSSL version 1.1.1-dev (0x10101000L)
BS2000-OSD
BSD-generic32
BSD-generic64
BSD-ia64
BSD-sparc64
BSD-sparcv8
BSD-x86
BSD-x86-elf
BSD-x86_64
Cygwin
Cygwin-i386
Cygwin-i486
Cygwin-i586
Cygwin-i686
Cygwin-x86
Cygwin-x86_64
DJGPP
MPE/iX-gcc
OS390-Unix
QNX6
QNX6-i386
UEFI
UWIN
VC-CE
VC-WIN32
VC-WIN64A
VC-WIN64A-masm
VC-WIN64I
aix-cc
aix-gcc
aix64-cc
aix64-gcc
android
android-armeabi
android-mips
android-x86
android64
android64-aarch64
android64-mips64
android64-x86_64
bsdi-elf-gcc
cc
darwin-i386-cc
darwin-ppc-cc
darwin64-debug-test-64-clang
darwin64-ppc-cc
darwin64-x86_64-cc
debug
debug-erbridge
debug-linux-ia32-aes
debug-linux-pentium
debug-linux-ppro
debug-test-64-clang
dist
gcc
haiku-x86
haiku-x86_64
hpux-ia64-cc
hpux-ia64-gcc
hpux-parisc-cc
hpux-parisc-gcc
hpux-parisc1_1-cc
hpux-parisc1_1-gcc
hpux64-ia64-cc
hpux64-ia64-gcc
hpux64-parisc2-cc
hpux64-parisc2-gcc
hurd-x86
ios-cross
ios64-cross
iphoneos-cross
irix-mips3-cc
irix-mips3-gcc
irix64-mips4-cc
irix64-mips4-gcc
linux-aarch64
linux-alpha-gcc
linux-aout
linux-arm64ilp32
linux-armv4
linux-c64xplus
linux-elf
linux-generic32
linux-generic64
linux-ia64
linux-mips32
linux-mips64
linux-ppc
linux-ppc64
linux-ppc64le
linux-sparcv8
linux-sparcv9
linux-x32
linux-x86
linux-x86-clang
linux-x86_64
linux-x86_64-clang
linux32-s390x
linux64-mips64
linux64-s390x
linux64-sparcv9
mingw
mingw64
nextstep
nextstep3.3
purify
qnx4
sco5-cc
sco5-gcc
solaris-sparcv7-cc
solaris-sparcv7-gcc
solaris-sparcv8-cc
solaris-sparcv8-gcc
solaris-sparcv9-cc
solaris-sparcv9-gcc
solaris-x86-gcc
solaris64-sparcv9-cc
solaris64-sparcv9-gcc
solaris64-x86_64-cc
solaris64-x86_64-gcc
tru64-alpha-cc
tru64-alpha-gcc
uClinux-dist
uClinux-dist64
unixware-2.0
unixware-2.1
unixware-7
unixware-7-gcc
vms-alpha
vms-alpha-p32
vms-alpha-p64
vms-ia64
vms-ia64-p32
vms-ia64-p64
vos-gcc
vxworks-mips
vxworks-ppc405
vxworks-ppc60x
vxworks-ppc750
vxworks-ppc750-debug
vxworks-ppc860
vxworks-ppcgen
vxworks-simlinux
The same problem exists to different degrees on Windows & Android...
I'm thinking "not really". You can't build fat libraries on those platforms, so the problem does not really exist. You still need to specify a specific path for a platform specific library, so what's the problem with headers?
There's some handwaiving since I recall seeing something about it in Linux (I can't find the reference at the moment), but Android does not have it.
Related, you can see a comprehensive list of platform and user configuration options with:
$ openssl version -a
OpenSSL 1.0.2g 1 Mar 2016
built on: reproducible build, date unspecified
platform: debian-amd64
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: cc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REE
NTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -g -O2 -fstack-protector-stron
g -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymboli
c-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32
_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_
ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIR
LPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/usr/lib/ssl"