3

我正在尝试使用 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

4

1 回答 1

2

所以我想知道是否可以将以下代码添加到我的一个 cpp 文件中以进行 FIPS 验证

class FIPSInitializer
{
public:
    FIPSInitializer()
    {
        FINGERPRINT_premain();
    }
    virtual ~FIPSInitializer()
    {
    }
};

嗯……这听起来很奇怪。进入 FIPS 模式的唯一方法是FIPS_mode_set. 如果您调用FIPS_mode_set并且它返回非零值,那么您使用的是经过验证的密码学。如果您调用FIPS_mode_set但失败,那么您仍然可以加密和解密(考虑“可插拔”架构),但您不会使用经过验证的密码学。有关详细信息,请参阅FIPS 模式集

只是猜测:如果FIPS_mode_set失败并且FINGERPRINT_premain没有被调用,那么您可能偏离了OpenSSL FIPS 140-2 安全策略所要求的程序。


fips_premain.c 将为 gcc、cl(Microsoft)、cl(Microsoft)、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 功能库。您可以随意转动 FIPS 功能库的旋钮,只要它不会危及神圣fipscanister.o和朋友。注意 with 的fips使用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,因为install还构建了组件(OpenSSL 上的耻辱)。在安装过程中,我相信共享对象将与神圣的fipscanister.o. 链接后,模块签名将嵌入到生成的可执行文件中fipsldfipsld由 OpenSSL 构建过程使用,并在内部调用一个名为incore. incore写入实际签名。


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

$ 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
...

当您的 makefile 调用LD时,它实际上是在调用 OpenSSL 的fipsld. fipsld将确保您的程序链接反对fipspremain.o,并在内部调用一个名为incore. incore将实际签名写入您的可执行文件或共享对象。以下来自openssl-fips-2.0.5makefile:

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.a他们将不得不跳过这些环节。CCFIPSLD_CC


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

注意:您不要fips_premain.c自己编译。


如果fips_premain.c在尝试构建 FIPS 对象模块时出现错误,那么您的平台不受支持。您应该联系 OpenSSL 基金会的 Steve Marquess 并安排一次有关验证平台的讨论。请参阅OpenSSL 和 FIPS 140-2OpenSSL FIPS 140-2 安全策略


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

解决办法是修改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 ...在编译时添加了fips_premain.c.

于 2013-12-01T05:55:53.407 回答