FIPS Build Guidelines

From OpenSSLWiki
Revision as of 14:45, 29 May 2013 by Stevem (talk | contribs) (Added code path and summary sections)

Jump to: navigation, search

The Security Policy document defines a very specific procedure for creating a binary module from the official source distributions:

gunzip -c openssl-fips-2.0.N.tar.gz | tar xf -
cd openssl-fips-2.0.N

(for Unix/Linux). The Security Policy and NIST CMVP web site entry also clearly state that the source distribution (tarball) cannot be modified, at all. The unofficial FIPS user Guide also notes this reestriction.

That is worth repeating as the question appears repeatedly: you cannot modify the contents of the official tarball. The CMVP has imposed that very specific prohibition on all of the OpenSSL FIPS Object Module validations. From the software developer/engineer perspective that prohibition is senseless and furstrating, but it is what it is. You can't modify the tarball, even if the tinest tweak would make the difference between success and failure in building the module for your platform of interest. The natural tendency of a software developer is to identify and implement the simplest and most elegant modification to fix a build or execution. That approach generally won't work when the goal is to claim FIPS 140-2 validated status for the resulting module.

Question: Okay, got it. The official canonical build commands given above must be used with an unmodified official tarball. The end result doesn't build a usable module for my platform if interest. Is there anything I can do?

Answer: Maybe.

The CMVP has provided specific guidance on some things that must be done (e.g. the canonical build commands) and some things that cannot be done (modification of the tarball contents). However, based on an extensive series of validations of specific platforms (Operational Environments in FIPS-speak) we can discern some general rules for a limited set of techniques that are presumptively permissible.

Environment scripts

The ./config command determines a build target from various inputs, for example the uname command for Unix/Linux systems for native compilation. For cross-compilation the target characteristics are determined from environment variables MACHINE, SYSTEM, RELEASE, etc. The use of a shell script that sets the appropriate environment variables is well established. For instance

# Cross-compile environment for Android on ARMv7
# This script assumes the Android NDK and the OpenSSL FIPS
# tarballs have been unpacked in the same directory

#android-sdk-linux/platforms Edit this to wherever you unpacked the NDK

if [ -d android-ndk-r8b ]; then
  export ANDROID_NDK=$PWD/android-ndk-r8b
if [ -d android-ndk-r8c ]; then
  export ANDROID_NDK=$PWD/android-ndk-r8c

# Edit to reference the incore script (usually in ./util/)
export FIPS_SIG=$PWD/openssl-fips-2.0.2/util/incore

for i in linux darwin
  if [ -d $ANDROID_NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/$i-x86/bin ]; then

export PATH

# Shouldn't need to edit anything past here.

export MACHINE=armv7l
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=arm
export CROSS_COMPILE="arm-linux-androideabi-"
export ANDROID_DEV="$ANDROID_NDK/platforms/android-14/arch-arm/usr"
export HOSTCC=gcc

So in general specification of information needed to define the cross-compilation target for the toolkit is premissible, provided that the contents of the original official tarball are not modified.

Build Utilities

Multiple validated platforms have also been cross-compiled with build utilities supplied and residing outside of the official source distribution workarea, e.g. which contains:

# FIPS_SIG is the tool for determining the incore fingerprint
#export FIPS_SIG=/usr/local/ssl/fingerprint-macho
export FIPS_SIG="`pwd`"/iOS/incore_macho

The "incore" utilties (incore, incore6x, msincore, incore_macho) calculate and insert the incore digest of the executable file linked with the FIPS module, and are not used during creation of the actual FIPS module proper (fipscanister.o, fipscanister.lib). Note most openssl-fips-2.0.N.tar.gz tarballs contain one or more incore utilities; these cannot be modified in place. However, specification of separate utility files residing outside of the unpacked tarball is permissible.

Code Path

The code path is an important concept. Modifications to the build environment that change the code path of the resulting binary code (e.g. adding/removing assembler optimizations, or changing between 32 and 64 bit code generation) mean that the original formally tested platform is no longer relevant.


Some limited modifications to the build environment are permissible provided that:

  • the contents of the official tarball are not modified, at all
  • the canonical build commands are used (gunzip ...; cd ...; ./config; make)
  • the code path is the same as for a formally tested platform