我是 openssl 的新手,我从 openssl 下载了 openssl-fips-2.0.1 代码,但是,我无法跟踪文档和安全策略中所述的 FIPS_mode_set() 的定义。然而,我确实在 fips.c 中找到了 fips_set_mode() ,但它们并不是指同一个,对吗?
定义在哪里? 请告诉我。
在 openssl 包中找不到 FIPS_mode_set() 代码
你必须知道如何提问...
openssl-1.0.1f$ grep -R FIPS_mode_set *
apps/openssl.c: if (!FIPS_mode_set(1)) {
CHANGES: *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
crypto/cpt_err.c:{ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"},
crypto/evp/evp_cnf.c: if (!FIPS_mode() && !FIPS_mode_set(1))
crypto/crypto.h:int FIPS_mode_set(int r);
crypto/o_fips.c:int FIPS_mode_set(int r)
Binary file fips_premain_dso matches
ssl/ssltest.c: if(!FIPS_mode_set(1))
util/libeay.num:FIPS_mode_set 3253 EXIST::FUNCTION:
openssl-1.0.1f$
声明位于
crypto/crypto.h
中,定义位于 crypto/o_fips.c
中。这是来自o_fips.c
:
int FIPS_mode_set(int r)
{
OPENSSL_init();
#ifdef OPENSSL_FIPS
#ifndef FIPS_AUTH_USER_PASS
#define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password"
#endif
if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS))
return 0;
if (r)
RAND_set_rand_method(FIPS_rand_get_method());
else
RAND_set_rand_method(NULL);
return 1;
#else
if (r == 0)
return 1;
CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
return 0;
#endif
}
如果您正在寻找
FIPS_mode_set
通过特殊设置进入“FIPS 模式”或切换某些算法,则这一步不会发生。
链接时会更早发生。幕后发生的事情是编译器
fipsld
,它会寻找LD
的调用。如果 LD
not 被调用,那么 fipsld
只会调用您的常规编译器(可能是 /usr/bin/gcc
)。如果它看到对 LD
的调用,那么它会做三件事。
首先,它编译
fips_premin.c
。然后它调用真正的 ld
来执行与所有目标文件及其生成的 fips_premain.o
的最终链接。最后,它调用incore
交换FIPS对象模块,计算相关text
和data
(相关指FIPS代码和数据)的签名,然后将签名嵌入到可执行文件中。
签名是使用 HMAC 生成的,密钥嵌入在可执行文件中。它没有什么特别之处,并且在世界各地的所有可执行文件中都是不变的。这是使用的密钥:
etaonrishdlcupfm
。
如果您在构建可执行文件时没有采取特殊步骤,那么您可能会遗漏一些步骤。以下是使用
fipsld
和 incore
的步骤:
$ export CC=`find /usr/local -name fipsld`
$ echo $CC
/usr/local/ssl/fips-2.0/bin/fipsld
$ export FIPSLD_CC=`find /usr/bin -name gcc`
$ echo $FIPSLD_CC
/usr/bin/gcc
现在,做一个标准的
config
和 make
。有时您必须先执行 config
,然后调整 CC
和 FIPSLD_CC
,然后运行 make
,因为某些 config
文件在排列时会卡住。有时您必须在 Makefile
之后打开 config
,然后将 CC
更改为 /usr/local/ssl/fips-2.0/bin/fipsld
。有很多方法可以解决特定的包装问题。
我从openssl下载了openssl-fips-2.0.1代码,但是,我无法追踪到FIPS_mode_set()的定义
openssl-fips-NNN
提供 FIPS 验证的加密技术 如果您根据安全策略构建 FIPS 对象模块。您可以在此处找到OpenSSL FIPS 1402-安全策略。
如果您所做的只是下载和构建
openssl-fips-NNN
,那么您可能没有使用经过 FIPS 验证的加密技术。有一个程序需要遵循,其中包括获取源代码的“可信”副本。您可以下载并验证签名,但需要一个经过 FIPS 验证的签名检查器,这会产生先有鸡还是先有蛋的问题,因为您无法从源代码构建它。因此,实际的解决方案是从 OpenSSL 基金会订购 CD。这很奇怪,但却是事实。例如,请参阅OpenSSL FIPS 用户指南 或OpenSSL FIPS 安全策略,附录 B,受控分发文件指纹。
构建并安装 FIPS 对象模块后,您可以构建该库的支持 FIPS 的版本。支持 FIPS 的 OpenSSL 将使用 FIPS 对象模块(如果可用)。将其视为“可插拔”架构。
库的 FIPS Capable 版本简单来说就是
openssl-NNN
,例如 openssl-1.0.1e
和 openssl-1.0.1f
。这是您所了解和喜爱的。
您还可以考虑将
ctags
作为源代码浏览器,以帮助您查找内容并跳转。请参阅 Sourceforge 上的Exuberant Ctags。
请参考头文件
crypto.h
。我可以在第 566 行找到它的定义,如下所示:
int FIPS_mode_set(int r);
文档清楚地提到它在头文件中
<openssl/crypto.h>
。
因此,在您的代码中,包含
openssl/crypto.h
以包含此函数的定义。如果您遇到其他问题,您可以浏览 OpenSSL 的问题,可能会对您有所帮助。
对于链接
FIPS_mode_set()
应可从 libcrypto
获得(*.a
用于静态链接,*.so
用于运行时链接)。
libcrypto.a/.so
附带您的发行版 openssl
的开发人员包,或者是您自己构建 openssl-x.y.z
的结果。
您可以在文件
FIPS_mode_set()
的 openssl-x.y.z
源中找到 crypto/o_fips.c
的源。
官方文档迁移指南解释了应该使用不同的功能:
https://www.openssl.org/docs/manmaster/man7/migration_guide.html
删除了 FIPS_mode() 和 FIPS_mode_set()
这些功能是旧版 API,不适用于新的提供商模型。应用程序应使用 EVP_default_properties_is_fips_enabled(3) 和 EVP_default_properties_enable_fips(3)。
我添加了这个(我仍然不确定它是否好,但希望应该适用于所有版本):
#if OPENSSL_VERSION_MAJOR < 3
FIPS_mode_set(0);
#else
EVP_default_properties_enable_fips(nullptr, 0);
#endif