在更多c ++编译器/平台上调用FINGERPRINT_premain

时间:2013-10-22 20:13:38

标签: c++ openssl fips

我正在尝试使用xlC_r作为编译器/链接器在IBM PLinux上以FIPS模式使用静态链接OpenSSL。 fipsld或fips_premain.c不支持此组合。 fipld将添加链接器选项以在{OSF1,IRIX,HP-UX,AIX,Darwin}中的uname -s上调用FINGERPRINT_premain,fips_premain.c将为gcc,cl(Microsoft),cc(SUN)和某些执行编译器特定的解决方案其他我不熟悉的人。不幸的是,IBM PLinux上的xlC_r没有被其中任何一个覆盖,所以我想知道是否可以将以下代码添加到我的一个cpp文件中以进行FIPS验证,或者如果我需要将我的编译器/链接器更改为gcc或是否需要另一个方式(链接器选项?)来保持xlC_r。请提供一些理由。

#if defined(PREMAIN_NOT_COVERED)
extern "C" void FINGERPRINT_premain(void);

class FIPSInitializer
{
public:
    FIPSInitializer()
    {
        FINGERPRINT_premain();
    }
    virtual ~FIPSInitializer()
    {
    }
};
extern FIPSInitializer fips_initializer;
FIPSInitializer fips_initializer;
#endif

我也尝试在链接时使用-Wl,init,FINGERPRINT_premain,但是在使用我们的共享库时,我们的测试会出现段错误。

OpenSSL用户指南: http://www.openssl.org/docs/fips/UserGuide-1.1.1.pdf

OpenSSL安全政策: http://www.openssl.org/docs/fips/SecurityPolicy-2.0.pdf

1 个答案:

答案 0 :(得分:2)

  

所以我想知道是否添加以下代码   我的一个cpp文件可用于FIPS验证

class FIPSInitializer
{
public:
    FIPSInitializer()
    {
        FINGERPRINT_premain();
    }
    virtual ~FIPSInitializer()
    {
    }
};
嗯......这听起来很奇怪。进入FIPS模式的唯一方法是FIPS_mode_set。如果您调用FIPS_mode_set并且它返回非零,那么您正在使用经过验证的加密。如果你打电话给FIPS_mode_set但它失败了,那么你仍然可以加密和解密(想想一个“可插拔的”架构),但你使用经过验证的加密。有关详细信息,请参阅FIPS mode set

只是推测:如果FIPS_mode_set失败并且未调用FINGERPRINT_premain,那么您可能会偏离OpenSSL FIPS 140-2 Security Policy所需的程序。


  

fips_premain.c将为gcc,cl(Microsoft)执行编译器特定的解决方案,   cl(微软),cc(SUN)和其他一些我不熟悉的人......

您不编译fips_premain.c。在构建FIPS对象模块或链接到FIPS对象模块时编译它。甚至有人谈论完全删除它。

除了以下之外的任何内容都会使FIPS构建过程失效,并且您将不会使用经过验证的加密。

$ export OPENSSL_INSTALLDIR=/usr/local/ssl/darwin
$ cd openssl-fips-2.0.5/
$ ./config
$ make
$ sudo make install

以上结果是fipscanister.o和朋友。您可以在$OPENSSL_INSTALLDIR\lib中找到它们(其中有四个):

$ ls /usr/local/ssl/darwin/lib/
fipscanister.o              fips_premain.c
fipscanister.o.sha1         fips_premain.c.sha1

在构建并安装FIPS对象模块之后,您可以构建FIPS Capable Library。您可以自由为FIPS Capable Library打开旋钮,只要它不会危及神圣的fipscanister.o和朋友。请注意 fips 与{{1}的使用}。

config

您必须使用$ cd openssl-1.0.1e/ $ ./config fips shared -no-ssl2 -no-ssl3 -no-comp -no-hw -no-engine \ --openssldir=$OPENSSL_INSTALLDIR \ --with-fipsdir=$OPENSSL_INSTALLDIR \ --with-fipslibdir=$OPENSSL_INSTALLDIR/lib/ $ make depend $ make all $ sudo -E make install ,因为-E也构建组件(OpenSSL上的耻辱)。在安装过程中,我相信共享对象将与神圣的install链接。链接后,模块签名将嵌入fipscanister.o生成的可执行文件中。 OpenSSL构建过程使用fipsld,并在内部调用名为fipsld的程序。 incore写下实际的签名。


在构建FIPS验证的可执行文件或共享对象时,您将执行以下操作:

incore

当你的makefile调用$ export CC=`find $OPENSSL_INSTALLDIR -name fipsld` $ echo $CC /usr/local/ssl/darwin/bin/fipsld $ export FIPSLD_CC=`find /usr/bin -iname gcc` $ echo $FIPSLD_CC /usr/bin/gcc # Now build your project via make (or though the command line): $ make ... 时,它真正调用了OpenSSL的LDfipsld将确保您的计划与fipsld相关联,并在内部调用名为fipspremain.o的程序。 incore将实际签名写入可执行文件或共享对象。以下内容来自incore makefile:

openssl-fips-2.0.5

如果您没有安装fips_premain_dso$(EXE_EXT): fips_premain.c $(CC) $(CFLAGS) -DFINGERPRINT_PREMAIN_DSO_LOAD -o $@ fips_premain.c \ $(FIPSLIBDIR)fipscanister.o ../libcrypto.a $(EX_LIBS) ,则可以在fipsld中找到它。只需将其复制到openssl-fips-2.0.5即可。我不记得$OPENSSL_INSTALLDIR\bin是否复制了它(我似乎记得提交了一份关于它的错误报告)。

您无法在静态库中嵌入签名。在构建make install时,OpenSSL无法执行此操作,而在构建libcrypto.a时则无法执行此操作。如果您向客户分发libmycoolness.a,他们必须跳过libmycoolness.aCC圈。


如果您不想跳过FIPSLD_CCCC箍,那么您应该在构建可执行文件或共享对象后链接fipscanister.o并手动运行FIPSLD_CC。但是,OpenSSL人员不推荐这样做。他们建议您使用incoreCC

注意:您自己不编译FIPSLD_CC


如果fips_premain.c在尝试构建FIPS对象模块时发生错误,则不支持您的平台。您应该联系OpenSSL Foundation的Steve Marquess并安排有关验证平台的讨论。请参阅OpenSSL and FIPS 140-2OpenSSL FIPS 140-2 Security Policy


相关的,如果由于C ++名称修饰而得到未定义的符号,请在OpenSSL wiki上查看Fipsld and C++

解决方案是修改fips_premain.c。它不是一个隔离源,所以你可以在合理的范围内修改它。在这种情况下,fipsld在为您编译fipsld++时会有效执行以下操作:

fips_premain.c

在编译${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \ -x c "${PREMAIN_C}" -x none \ ${_WL_PREMAIN} "$@" 时,有效地添加了${CC} -x c fips_premain.c -x none ...