Skip to content
Advertisement

FIPS Capable OpenSSL cross-compiled: incore fingerprint issue

I’m having an issue trying to use the OpenSSL shared library (libcrypto) compiled to be FIPS capable on a MIPS device.
I cross-compiled the FIPS Object Module and then the OpenSSL library in the following way (summarizing):

export FIPS_SIG=<my_path>/incore
./config fips --with-fipsdir=<my_path>/fips-2.0
make depend
make
make install

I did all the needed steps, so I’m able to compile and install the library.
The issue appears when I try to run the FIPS_mod_set(1) API from an application linking the OpenSSL library.
The FIPS mode initialization fails receiving this error:

2010346568:error:2D06B06F:lib(45):func(107):reason(111):NA:0:

Debugging the FIPS code, I found that the issue is inside the FIPS_check_incore_fingerprint(void) function:
the check memcmp(FIPS_signature,sig,sizeof(FIPS_signature)) fails.
Going deeper in the debug I discovered that the FIPS_signature value remains the default one, so I have the doubt that the incore script, called by the fipsld utility, is not embedding properly the fingerprint inside the OpenSSL shared object.
How can I check if the incore script embedded the fingerprint inside the shared object?
How can I print the expected fingerprint?
Do I need to adapt the incore script? (I suppose it’s not allowed)
Do you have any suggestion?
Thanks a lot!

P.S.: I’m cross-compiling using an x86 Linux machine.

Advertisement

Answer

I found the issue! I’ll try to explain the whole debugging process and the solution.

INTRODUCTION:

When OpenSSL is configured to be FIPS capable, during the compilation the Makefile calls a utility, fipsld, which both performs the check of the FIPS Object Module and generates the new HMAC-SHA-1 digest for the application executable (as explained in the official OpenSSL user guide https://www.openssl.org/docs/fips/UserGuide-2.0.pdf)

The fipsld command requires that the CC and FIPSLD_CC environment variables be set, with the latter taking precedence.
In the Makefile you will find something like this:

libcrypto$(SHLIB_EXT): libcrypto.a fips_premain_dso$(EXE_EXT)
    @if [ "$(SHLIB_TARGET)" != "" ]; then 
        if [ "$(FIPSCANLIB)" = "libcrypto" ]; then 
            FIPSLD_LIBCRYPTO=libcrypto.a ; 
            FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; 
            export CC FIPSLD_CC FIPSLD_LIBCRYPTO; 
        fi; 
        $(MAKE) -e SHLIBDIRS=crypto  CC="$${CC:-$(CC)}" build-shared && 
        (touch -c fips_premain_dso$(EXE_EXT) || :); 
    else 
        echo "There's no support for shared libraries on this platform" >&2; 
        exit 1; 
    fi

Then, the fipsld utility invokes a shell script, incore, used to embed the FIPS Object Module’s expected fingerprint in the OpenSSL shared object. It’s important to specify the incore path via FIPS_SIG env variable, e.g.:

export FIPS_SIG=$PWD/openssl­fips­2.0/util/incore

DEBUGGING:

Debugging the incore script, I could see that the script tried to embed the signature into the shared object at the offset 0x001EE6B0 while the FIPS_signature symbol inside the shared object was located at a different offset, to be more specific at 0x001F0630:

objdump -t libcrypto.so.1.0.0 | grep FIPS_signature
001f0630 g     O .data  00000014              FIPS_signature

readelf -a libcrypto.so.1.0.0 | grep FIPS_signature
   870: 001f0630    20 OBJECT  GLOBAL DEFAULT   18 FIPS_signature
  3925: 001f0630    20 OBJECT  GLOBAL DEFAULT   18 FIPS_signature

Furthermore dumping the shared object I wasn’t able to find the generated signature at the offset 0x001EE6B0 so I reached the conclusion that the shared object was edited after the signature embedding procedure by some other process.

SOLUTION:

I was using a package Makefile for the OpenSSL packet formatted in the following way:

$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)
    <options>
    all
$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)
    <options>
    build-shared
rm $(PKG_BUILD_DIR)/libssl.so.*.*.*
$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)
    <options>
    do_linux-shared
$(MAKE) -C $(PKG_BUILD_DIR)
    <options>
    install

As suspected, make build-shared and make do_linux-shared commands were responsible for changing the shared object in the wrong way.
NOTICE that make build-shared was called without using the proper environment variables.

I changed the package Makefile:

$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)
    <options>
    all
$(MAKE) -C $(PKG_BUILD_DIR)
    <options>
    install

Now the FIPS_check_incore_fingerprint(void) function returns with success and everything is working fine!

NOTE:

The following guide for Android devices has been very useful to find the proper solution. https://wiki.openssl.org/index.php/FIPS_Library_and_Android

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement