Bug 1009707

Summary: Need FIPS-140 update to self tests
Product: Red Hat Enterprise Linux 6 Reporter: Steve Grubb <sgrubb>
Component: cryptsetup-luksAssignee: Ondrej Kozina <okozina>
Status: CLOSED ERRATA QA Contact: Ondrej Moriš <omoris>
Severity: high Docs Contact:
Priority: urgent    
Version: 6.6CC: agk, arubin, coughlan, eparis, gmazyland, jherrman, okozina, prajnoha, prockai, sforsber, sgrubb, tlavigne, tmraz, zkabelac
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: cryptsetup-luks-1.2.0-10.el6 Doc Type: Enhancement
Doc Text:
FIPS products are now defined by the presence of the dracut-fips package in the system. During the initialization of a library, a cryptographic module is supposed to determine if the library is a FIPS product to reduce the amount of required integrity tests. For this purpose, a new constructor function has been added to the cryptsetup-libs library. The constructor detects if the /etc/system-fips file, which is a part of dracut-fips, exists in the system, and determines if a FIPS integrity test is needed.
Story Points: ---
Clone Of:
: 1038097 (view as bug list) Environment:
Last Closed: 2014-10-14 08:21:20 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1013077, 1056252    

Description Steve Grubb 2013-09-18 23:22:57 UTC
Description of problem:
FIPS-140 now requires us to define a FIPS product. We define the product as the packages + a special -fips subpackage that has the hmac file in it. Because dm-crypt is being re-evaluated and cryptsetup-luks is in the crypto boundary, we need a .ctor function of the library to do a FIPS integrity test to met new guidance we recently were given. You might see bz #999867 for more information.

Comment 3 Ondrej Kozina 2013-10-07 07:00:24 UTC
Short summary:

- file checked to indicate fips mode: /etc/system-fips
- added constructor function to cryptsetup library
- added constructor function to cryptsetup utility

the checks in constructor functions work according to this table:

              | /etc/system-fips | no /etc/system-fips
--------------+------------------+----------------------
fips flag     |       enforce    |    no test/no fips
--------------+------------------+------
no fips flag  |       test       |    no test


in case of "no fips flag" X "/etc/system-fips": checksum failures are silent in library constructor. utility issues warning only.

Comment 5 Ondrej Kozina 2013-10-10 10:49:28 UTC
(In reply to Ondrej Kozina from comment #3)
> - added constructor function to cryptsetup utility

new build removes this constructor as it's not required by crypto boundary.

Comment 6 Ondrej Moriš 2013-10-30 12:23:01 UTC
Unfortunately, cryptsetup-luks does not respect the table from c#3:

(A) FIPS flag & no /etc/system-fips 

1. Passing POST situation (it should work and it does work)

# dd if=/dev/zero of=/tmp/encrypted.img count=1 bs=4k seek=100k
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000873922 s, 4.7 MB/s
# losetup /dev/loop0 /tmp/encrypted.img
# echo "test password" > /tmp/test_pass
# cryptsetup luksFormat /dev/loop0 -d /tmp/test_pass -q -v
Command successful.
# echo $?
0
# losetup -d /dev/loop0

2. Failing POST situation (it should work but it does not)

# prelink /lib64/libcryptsetup.so.1 // to simulate POST failure
# dd if=/dev/zero of=/tmp/encrypted.img count=1 bs=4k seek=100k
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000676768 s, 6.1 MB/s
# losetup /dev/loop0 /tmp/encrypted.img.
# echo "test password" > /tmp/test_pass
# cryptsetup luksFormat /dev/loop0 -d /tmp/test_pass -q -v
libgcrypt selftest: binary  (0): Selftest failed (/lib64/.libgcrypt.so.11.hmac)
Not compatible PBKDF2 options (using hash algorithm sha1).
Command failed with code 22: Not compatible PBKDF2 options (using hash algorithm sha1).
# echo $?
1

Comment 7 Tom Coughlan 2013-10-30 17:41:50 UTC
Suzanne suggested: "Since we have deferred FIPS certification for dm-crypt until RHEL 6.6, I believe that rather than fixing the bug with a new patch, we could 
choose to revert the package from 6.5, and address the FIPS requirements 
in 6.6."

I checked with Alasdair and he confirmed that this bug is the only change in the package for 6.5. 

So, we can revert to the 6.4 version of the package, _if_ the FIPS team confirms that there are no other changes in RHEL 6.5 that require the change. 

Tom

Comment 8 Steve Grubb 2013-10-30 17:47:47 UTC
The kernel is the only dependency and it's validation was deferred to 6.6 because nss was not ready for fips certification. So, its safe to push kernel and this package into the same certification.

Comment 10 Ondrej Kozina 2013-10-31 12:33:52 UTC
First of all, this is _not_ a flaw in POST mechanics in cryptsetup library. The table is valid as described in comment#3.

What is failing is subsequent call to libgrcypt where algo == 2 (sha1).
gcry_md_open(&h->hd, algo, GCRY_MD_FLAG_HMAC).

Tomas, please can you give me your opinion on this?

Comment 11 Tomas Mraz 2013-10-31 12:39:44 UTC
The table does not apply to libgcrypt because it does not and can not respect the /etc/system-fips non-presence as the flag for not doing the self-testing including the integrity check. There is currently no plan to revalidate libgcrypt as a FIPS module in RHEL-6 so we cannot change this.

This should be fixed in RHEL-7 however.

Comment 12 Tomas Mraz 2013-10-31 12:42:03 UTC
Also this is not a real bug in libgcrypt but rather feature of the libgcrypt FIPS module.

Comment 13 Tomas Mraz 2013-10-31 12:47:36 UTC
So basically you cannot test for the upper right corner of the table above in RHEL-6. It makes sense to do that in RHEL-7 though.

Comment 14 Steve Grubb 2013-10-31 13:05:14 UTC
In talking with Tomas, he said that this is failing because libgcrypt sees the fips-1 flag and it was prelinked. This would be an invalid test. For any and all fips testing, we have to assume the user followed that part of the setup instructions whenever fips=1 is being passed. If it was re-tested where everything was unprelinked and the dracut-fips package was not installed and libgcrypt was being used with algorithms it accepts in fips mode and it still failed, then we have aproblem.

Comment 15 Tomas Mraz 2013-10-31 13:05:39 UTC
Or more exactly - you cannot test for the upper right corner by enabling prelink. You must just individually corrupt the .hmac file of libcryptsetup.

Comment 16 Ondrej Moriš 2013-10-31 13:17:08 UTC
Well, so it actually means that cryptsetup-luks was working fine but the issue in libgcrypt was mistakenly considered to be the problem in cryptsetup-luks. 

With prelink disabled (and hmac corrupted) it works as expected.

> For any and all fips testing, we have to assume the user followed that part of > the setup instructions whenever fips=1 is being passed. 

I must say I am getting confused here. I thought this already has been discussed and the decision was made that the top-right corner case represents "misconfigured" system. FIPS product <=> kernel fips parameter set to 1 & /etc/system-fips. It is well known that you cannot have prelinked cryptographic modules in FIPS product. But you can have all prelinked if there is not FIPS product (ie. all cases except the top-left one). 

I was always curious what will happen with cryptographic modules which are not going to be (re-)certified in RHEL 6.6 (afaik this apply only to libgcrypt right now). They will obviously not respect "FIPS product" definition and it will cause issues like this even in a non-FIPS mode (top-right corner). For instance, (since prelink is used by default) anything linking libgcrypt will be broken in the top-right case until RHEL7. Are we okay with that?

If so, we should explicitly say somewhere that whenever fips kernel parameter is set to 0, all should be un-prelinked and the prelinking must be disabled regardless of FIPS product.

Comment 17 Tomas Mraz 2013-10-31 13:29:05 UTC
(In reply to Ondrej Moriš from comment #16)
> If so, we should explicitly say somewhere that whenever fips kernel
> parameter is set to 0, all should be un-prelinked and the prelinking must be
> disabled regardless of FIPS product.

I think you mean 1 above instead of 0. Yes, but we are saying that in the libgcrypt FIPS module security policy.

I think the upper right quadrant is hardly a problem as customers would normally never reach it. The remaining quadrants is what is much more interesting for testing.

Comment 25 Ondrej Kozina 2014-06-20 09:42:15 UTC
Adding table with actual implementation and detailed description. When testing, please bear in mind information in comments #12 to #17

       | /etc/system-fips | no /etc/system-fips
-------+------------------+----------------------
   kff |     enforce      |    no test/no fips
-------+------------------+----------------------
no kff |   test/no fips   |    no test/no fips

'kff'    : kernel fips flag set to 1
'no kff' : kernel fips flag set to 0

"kff' X /etc/system-fips": POST fails with error if either checksums are missing or don't match. This is the only configuration where cryptsetup library operates under FIPS restrictions if POST pass.

"no kff X /etc/system-fips": Provided checksums are missing or don't match, POST issues same error message as "kff X /etc/system-fips" configuration but it doesn't fail with error. the cryptsetup is not considered to be running in FIPS mode even if it pass POST.

"no /etc/system-fips x kff": POST is skipped completely and the cryptsetup is not considered to be running in FIPS mode (no restrictions on library with regard to FIPS)

"no /etc/system-fips x no kff": same as above

Comment 27 Ondrej Moriš 2014-08-12 08:42:04 UTC
Successfully verified with cryptsetup-luks-1.2.0-11.el6 on i386 and x86_64 (waiting for ppc64 results):

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [   LOG    ] :: a) fips=1 + /etc/system-fips (correct FIPS mode)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: [   LOG    ] :: POST should proceed and must PASS
:: [   LOG    ] :: Checking FIPS mode status
:: [   LOG    ] :: OpenSSL working in new FIPS mode, 1024 bit RSA disallowed!
:: [   LOG    ] :: FIPS mode is enabled
:: [   PASS   ] :: Checking that FIPS is enabled (Expected 0, got 0)
:: [   LOG    ] :: Disk Encryption
:: [   PASS   ] :: Checking POST (pass) (Expected 0, got 0)
:: [   PASS   ] :: Clean-up (Expected 0, got 0)
:: [   PASS   ] :: Corrupting /lib/.libcryptsetup.so.1.hmac (Expected 0, got 0)
:: [   INFO   ] :: rlRun: command = '
  dd if=/dev/zero of=/tmp/encr.img count=1 bs=4k seek=100k &&
  losetup /dev/loop0 /tmp/encr.img &&                      
  echo 'test password' > /tmp/test_pass &&
  cryptsetup luksFormat /dev/loop0 -d /tmp/test_pass -q -v'; 
  exitcode = 1; expected = 1

1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000267049 s, 15.3 MB/s
FIPS checksum verification failed.

:: [   PASS   ] :: Checking POST (fail) (Expected 1, got 1)
:: [   PASS   ] :: File '/var/tmp/tmp.8HRs2Xq1ie' should contain 'FIPS checksum verification failed.' 
:: [   PASS   ] :: Clean-up (Expected 0, got 0)
:: [   PASS   ] :: Restoring /lib/.libcryptsetup.so.1.hmac (Expected 0, got 0)
:: [   LOG    ] :: Duration: 43s
:: [   LOG    ] :: Assertions: 14 good, 0 bad
:: [   PASS   ] :: RESULT: a) fips=1 + /etc/system-fips (correct FIPS mode)

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [   LOG    ] :: b) fips=0 - /etc/system-fips (correct non-FIPS mode)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: [   PASS   ] :: Disabling FIPS (Expected 0, got 0)
:: [   PASS   ] :: Removing dracut-fips package (Expected 0, got 0)
:: [   PASS   ] :: Re-generating init ramdisk (Expected 0, got 0)
:: [   LOG    ] :: POST might proceed and but results must not be enforced
:: [   LOG    ] :: Checking FIPS mode status
:: [   LOG    ] :: OpenSSL working in new FIPS mode, 1024 bit RSA disallowed!
:: [   LOG    ] :: FIPS mode is disabled
:: [   PASS   ] :: Checking that FIPS is disabled (Expected 1, got 1)
:: [   LOG    ] :: Disk Encryption
:: [   PASS   ] :: Checking POST (pass) (Expected 0, got 0)
:: [   PASS   ] :: Clean-up (Expected 0, got 0)
:: [   PASS   ] :: Corrupting /lib/.libcryptsetup.so.1.hmac (Expected 0, got 0)
:: [   INFO   ] :: rlRun: command = '
  dd if=/dev/zero of=/tmp/encr.img count=1 bs=4k seek=100k &&
  losetup /dev/loop0 /tmp/encr.img &&
  echo 'test password' > /tmp/test_pass &&
  cryptsetup luksFormat /dev/loop0 -d /tmp/test_pass -q -v'; 
  exitcode = 0; expected = 0

1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000221404 s, 18.5 MB/s
Command successful.

:: [   PASS   ] :: Checking POST (pass) (Expected 0, got 0)
:: [   PASS   ] :: Clean-up (Expected 0, got 0)
:: [   PASS   ] :: Restoring /lib/.libcryptsetup.so.1.hmac (Expected 0, got 0)
:: [   LOG    ] :: Duration: 16s
:: [   LOG    ] :: Assertions: 21 good, 0 bad
:: [   PASS   ] :: RESULT: b) fips=0 - /etc/system-fips (correct non-FIPS mode)

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [   LOG    ] :: c) fips=0 + /etc/system-fips (misconfiguration)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: [   PASS   ] :: Installing dracut-fips package (Expected 0, got 0)
:: [   LOG    ] :: POST might proceed but results must not be enforced
:: [   LOG    ] :: Checking FIPS mode status
:: [   LOG    ] :: OpenSSL working in new FIPS mode, 1024 bit RSA disallowed!
:: [   LOG    ] :: FIPS mode is misconfigured
:: [   PASS   ] :: Checking that FIPS is misconfigured (Expected 2, got 2)
:: [   LOG    ] :: Disk Encryption
:: [   PASS   ] :: Checking POST (pass) (Expected 0, got 0)
:: [   PASS   ] :: Clean-up (Expected 0, got 0)
:: [   PASS   ] :: Corrupting /lib/.libcryptsetup.so.1.hmac (Expected 0, got 0)
:: [   INFO   ] :: rlRun: command = 
   'dd if=/dev/zero of=/tmp/encr.img count=1 bs=4k seek=100k &&
    losetup /dev/loop0 /tmp/encr.img &&
    echo 'test password' > /tmp/test_pass &&
    cryptsetup luksFormat /dev/loop0 -d /tmp/test_pass -q -v'; 
    exitcode = 0; expected = 0

1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.00284159 s, 1.4 MB/s
FIPS checksum verification failed.
Command successful.

:: [   PASS   ] :: Checking POST (pass & warn) (Expected 0, got 0)
:: [   PASS   ] :: File '/var/tmp/tmp.K4GszjdZdZ' should contain 'FIPS checksum verification failed.' 
:: [   PASS   ] :: Clean-up (Expected 0, got 0)
:: [   PASS   ] :: Restoring /lib/.libcryptsetup.so.1.hmac (Expected 0, got 0)
:: [   PASS   ] :: Re-generating init ramdisk (Expected 0, got 0)
:: [   PASS   ] :: Enabling FIPS (Expected 0, got 0)
:: [   LOG    ] :: Duration: 5m 45s
:: [   LOG    ] :: Assertions: 24 good, 1 bad
:: [   PASS   ] :: RESULT: c) fips=0 + /etc/system-fips (misconfiguration)

Case d) "fips=1 - /etc/system-fips" is not tested since it represents serious misconfiguration.

Comment 29 errata-xmlrpc 2014-10-14 08:21:20 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHEA-2014-1593.html