4

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.

neoben
  • 743
  • 12
  • 30
  • Just an FYI... Only one MIPS platform has been validated. Its the VxWorks 6.8 operational environment with a TI TNETV1050 processor. Also see the [OpenSSL FIPS 140-2 Security Policy, v 2.0. pp. 9-10](https://www.openssl.org/docs/fips/SecurityPolicy-2.0.pdf). – jww Mar 24 '17 at 16:21
  • [Here](https://stackoverflow.com/questions/35664412/unable-to-build-a-working-fips-capable-openssl-on-hp-ux)'s a question that I asked a while ago when I had a somehow related problem. For debugging purposes you can alter any file (I did it for _fips\_premain.c_, _fips.c_, _fipsld_), but when building the "official" version you must not change anything (actually there are lots of restrictions). Also, make sure that your platform/architecture pair is supported. – CristiFati Mar 24 '17 at 16:23
  • There's a fair amount of information missing form the question that might be useful. Rather than guessing at the potential problem, maybe the [User Guide for the OpenSSL FIPS Object Module v2.0](https://www.openssl.org/docs/fips/UserGuide-2.0.pdf) would be a good start. – jww Mar 24 '17 at 16:31
  • I'm aware of all the restriction related to the FIPS usage and I studied with precision all the documentation. I know that the FIPS Object Module cannot be changed but I'm trying to understand how to integrate that with my cross-compiled OpenSSL Library. Probably I found a clue: the incore script is coping the fingerprint in the wrong offstet of the shared library. It's probably an issue related to the ELF path (and the cross-compiled executables). I'll keep you posted. Thanks! – neoben Mar 24 '17 at 16:42

1 Answers1

4

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

neoben
  • 743
  • 12
  • 30
  • "I could see that the script tried to embed the signature into the shared object at the offset 0x001EE6B0" Would you mind explaining how you found this? Thanks! – zachwhaley Feb 16 '18 at 14:29
  • 1
    I printed the offset used inside the incore script (patching the code) and I compared the offset with the one resulted from the objdump inspection – neoben Feb 16 '18 at 14:44