stefanberger / swtpm

Libtpms-based TPM emulator with socket, character device, and Linux CUSE interface.
Other
564 stars 136 forks source link

Determine whether OpenSSL needs to be configured (FIPs, SHA1 s… …ignature) #878

Closed stefanberger closed 3 weeks ago

stefanberger commented 1 month ago

Get the list of enabled 'RuntimeAlgorithms' from libtpms and determine whether any of these enabled algorithms is disabled in OpenSSL due to FIPS mode. If FIPS mode on the host is enabled then disabled FIPS mode in OpenSSL so that the TPM 2 can function properly.

The following algorithms are disabled when OpenSSL is in FIPS mode:

Per openssl-ciphers man page it should be possible to disable the following algorithms use by cipher-suites:

WIP: It's not clear at what API level these are disabled. I have not been able to use !SHA256 to disabled SHA256.

stefanberger commented 1 month ago

@elmarco @berrange These are for now the unchanged remainders of the original profiles PR. I believe swtpm still needs to check whether FIPs mode is enabled in OpenSSL but maybe display an error message if it is and algorithms are not functioning and exit, OR allow to disable FIPS mode in the OpenSSL instance if the user passed a command line option.

stefanberger commented 1 month ago

It seems there are different ways we could disable the enforcement of disabled algorithms on a host:

My current thinking is to

  1. check for FIPS mode enabled and
  2. if it is enabled test candidate algorithms to be disabled by FIPS mode
  3. then disable FIPS mode if necessary and
  4. then test the same candidate algorithms again and possibly more
  5. and exit with error if any algorithm fails

This is a test program:

#include <openssl/evp.h>
#include <openssl/conf.h>

int main(void)
{
//    OPENSSL_no_config();
//    EVP_default_properties_enable_fips(NULL, 1);

    printf("AES-128-CFB: %d\n", EVP_CIPHER_fetch(NULL, "AES-128-CFB", NULL));
    printf("AES-256-CFB: %d\n", EVP_CIPHER_fetch(NULL, "AES-256-CFB", NULL));
    printf("CAMELLIA-128-CFB: %d\n", EVP_CIPHER_fetch(NULL, "CAMELLIA-128-CFB", NULL));
    printf("CAMELLIA-256-CFB: %d\n", EVP_CIPHER_fetch(NULL, "CAMELLIA-256-CFB", NULL));
    printf("DES-EDE3-CFB: %d\n", EVP_CIPHER_fetch(NULL, "DES-EDE3-CFB", NULL));

    EVP_default_properties_enable_fips(NULL, 0);

    printf("AES-128-CFB: %d\n", EVP_CIPHER_fetch(NULL, "AES-128-CFB", NULL));
    printf("CAMELLIA-128-CFB: %d\n", EVP_CIPHER_fetch(NULL, "CAMELLIA-128-CFB", NULL));
    printf("CAMELLIA-256-CFB: %d\n", EVP_CIPHER_fetch(NULL, "CAMELLIA-256-CFB", NULL));
    printf("DES-EDE3-CFB: %d\n", EVP_CIPHER_fetch(NULL, "DES-EDE3-CFB", NULL));
}

On a FIPS-enabled FC-40 host this prints:

AES-128-CFB: 1005757168
AES-256-CFB: 1005756496
CAMELLIA-128-CFB: 0
CAMELLIA-256-CFB: 0
DES-EDE3-CFB: 0
AES-128-CFB: 1005653632
CAMELLIA-128-CFB: 1005727792
CAMELLIA-256-CFB: 1005725840
DES-EDE3-CFB: 1005741520

Per this man page here https://docs.openssl.org/3.0/man1/openssl-ciphers/#cipher-strings it seems to be necessary to test availability of the following algorithms:

Thought "fips=yes" does have some other meanings not covered via the cipherstrings.