Skip to content

OpenSSL 3: OpenSSL.fips_mode returns false in FIPS enabled environment #605

@junaruga

Description

@junaruga

Here is another FIPS specific issue with OpenSSL 3 on RHEL 9.1 with FIPS mode enabled. The reason is because the macro OPENSSL_FIPS is not used in OpenSSL 3 any more.

The OpenSSL.fips_mode returns "false" in the environment.

# cat /etc/redhat-release 
Red Hat Enterprise Linux release 9.1 (Plow)

# fips-mode-setup --check
FIPS mode is enabled.

# echo $?
0

# openssl version
OpenSSL 3.0.1 14 Dec 2021 (Library: OpenSSL 3.0.1 14 Dec 2021)

# ruby -v
ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x86_64-linux]

# gem list | grep openssl
openssl (default: 2.2.1)

# ruby -e 'require "openssl"; p OpenSSL.fips_mode'
false

Here is the part of the code.

openssl/ext/openssl/ossl.c

Lines 417 to 428 in fbb24fd

static VALUE
ossl_fips_mode_get(VALUE self)
{
#ifdef OPENSSL_FIPS
VALUE enabled;
enabled = FIPS_mode() ? Qtrue : Qfalse;
return enabled;
#else
return Qfalse;
#endif
}

Here is the gdb log.

# gdb -q -ex "set breakpoint pending on" --ex "set debuginfod enabled on" --args ruby -e 'require "openssl"; p OpenSSL.fips_mode'

(gdb) b main
Breakpoint 1 at 0x1130: file ./main.c, line 38.

(gdb) b ossl_fips_mode_get
Function "ossl_fips_mode_get" not defined.
Breakpoint 2 (ossl_fips_mode_get) pending.

(gdb) r

<..snip..>

(gdb) f
#0  ossl_fips_mode_get (self=140737288759560)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/ext/openssl/ossl.c:406
406	{

(gdb) l
401	 * call-seq:
402	 *   OpenSSL.fips_mode -> true | false
403	 */
404	static VALUE
405	ossl_fips_mode_get(VALUE self)
406	{
407	
408	#ifdef OPENSSL_FIPS
409	    VALUE enabled;
410	    enabled = FIPS_mode() ? Qtrue : Qfalse;

(gdb) n
413	    return Qfalse;

(gdb) bt
#0  ossl_fips_mode_get (self=140737288759560)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/ext/openssl/ossl.c:413
#1  0x00007ffff7e64302 in vm_call_cfunc_with_frame (ec=0x55555555de90, 
    reg_cfp=0x7ffff77fdfa0, calling=<optimized out>)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/vm_insnhelper.c:2931
#2  0x00007ffff7e68017 in vm_sendish (ec=0x55555555de90, reg_cfp=0x7ffff77fdfa0, 
    cd=0x55555575d410, block_handler=<optimized out>, 
    method_explorer=<optimized out>)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/vm_callinfo.h:336
#3  0x00007ffff7e6c4e8 in vm_exec_core (ec=0x55555555de90, initial=0)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/insns.def:789
#4  0x00007ffff7e83f30 in rb_vm_exec (ec=0x55555555de90, 
    mjit_enable_p=<optimized out>)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/vm.c:2179
#5  0x00007ffff7ce833f in rb_ec_exec_node (ec=ec@entry=0x55555555de90, 
    n=n@entry=0x7ffff419c9a8)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/eval.c:317
#6  0x00007ffff7ce845a in ruby_run_node (n=0x7ffff419c9a8)
    at /usr/src/debug/ruby-3.0.4-160.el9_0.x86_64/eval.c:375
#7  0x000055555555518f in main (argc=<optimized out>, argv=<optimized out>)
    at ./main.c:50

(gdb) c
Continuing.
false
[Inferior 1 (process 13802) exited normally]

It seems that OPENSSL_FIPS implementation was deleted at the commit openssl/openssl@b53338c.

diff --git a/Configure b/Configure
index 4404963aa7..f6d5a7cfd3 100755
--- a/Configure
+++ b/Configure
...
-    if ($config{fips}) {
-       push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
-    }
-
...

I checked the FIPS related documents on OpenSSL repository. We need to add an implementation to make the Ruby OpenSSL work with OpenSSL 3 with the FIPS enabled environment.

$ pwd
/home/jaruga/git/openssl

$ find doc/ -name "*fips*"
doc/man7/fips_module.pod
doc/man5/fips_config.pod
doc/man1/openssl-fipsinstall.pod.in

$ find doc/ -name "*FIPS*"
doc/man7/OSSL_PROVIDER-FIPS.pod

The man 7 fips_module: https://github.com/openssl/openssl/blob/master/doc/man7/fips_module.pod

Note that the old functions FIPS_mode() and FIPS_mode_set() are no longer present so you must remove them from your application if you use them.
Applications written to use the OpenSSL 3.0 FIPS module should not use any legacy APIs or features that avoid the FIPS module. Specifically this includes:

  • Low level cryptographic APIs (use the high level APIs, such as EVP, instead)
  • Engines
  • Any functions that create or modify custom "METHODS" (for example EVP_MD_meth_new(), EVP_CIPHER_meth_new(), EVP_PKEY_meth_new(), RSA_meth_new(), EC_KEY_METHOD_new(), etc.)

All of the above APIs are deprecated in OpenSSL 3.0 - so a simple rule is to avoid using all deprecated functions. See migration_guide(7) for a list of deprecated functions.

The man 7 migration_guide: https://github.com/openssl/openssl/blob/master/doc/man7/migration_guide.pod

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions