Enable the FIPS mode in the library level

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Enable the FIPS mode in the library level

Alan Dean
Hi All:

I am working on a project to integrate the OpenSSL FIPS capable library into our product platform. (We will be doing our own FIPS 140-2 level 1 certification)

There are a large number of third party applications/ library (e.g. wget, libcurl, postfix, etc) run on our platform which use OpenSSL library, and based on the OpenSSL FIPS Library User Guide, it seems like the only way to make all these third party applications capable of running on FIPS mode will require modifying all these software to inject the FIPS_mode_set() API into the appropriate spots, so that FIPS mode can be explicitly enabled. This solution, however, may not be scalable since we would need to modify tens (if not hundreds) of different open source applications/ libraries in order to make them FIPS capable.

Another potential option I am investigating is, instead of having to invoke the FIPS_mode_set API from each application, maybe (or maybe not)  it's feasible to make the FIPS_mode_set API to be invoked in an entry point of the OpenSSL library so that the library itself will always be operating on FIPS mode, and in that case we won't need to inject the FIPS_mode_set API into all these third party software in order to make them FIPS capable. Of course there will be something like OpenSSH which will still require a lot of changes in order to make it able to run on FIPS mode without issue, but I will assume most of the other third party software will probably require no changes if we can enable the FIPS mode in the library level?

Question 1: Is it even feasible to make the FIPS mode always enabled for the whole OpenSSL library (i.e. for both libcrypto and libssl), so that most the applications which dynamically linked to libcrypto and libssl will be automatically use OpenSSL FIPS mode without the need of changes to add the FIPS_mode_set invocation (with some exception such as OpenSSH which may still need some fixes). (Assuming from certification's perspective we are ok if we may these changes)


Question 2: If the above idea is feasible, where in the OpenSSL library will be the best entry to invoke FIPS_mode_set API, so that we can make the whole OpenSSL library always in FIPS mode? Any potebtial issues for this solution?


Any suggestions will be greatly appreciated.




--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Dr. Matthias St. Pierre



On 05.03.2018 10:46, Alan Dean wrote:
Question 1: Is it even feasible to make the FIPS mode always enabled for the whole OpenSSL library (i.e. for both libcrypto and libssl), so that most the applications which dynamically linked to libcrypto and libssl will be automatically use OpenSSL FIPS mode without the need of changes to add the FIPS_mode_set invocation (with some exception such as OpenSSH which may still need some fixes). (Assuming from certification's perspective we are ok if we may these changes)


Question 2: If the above idea is feasible, where in the OpenSSL library will be the best entry to invoke FIPS_mode_set API, so that we can make the whole OpenSSL library always in FIPS mode? Any potebtial issues for this solution?


Any suggestions will be greatly appreciated.



The optimal location for inserting the FIPS_mode_set(1) call is probably OPENSSL_init()  (openssl-1.0.2/crypto/o_fips.c), see code snippet below.

void OPENSSL_init(void)
{
    static int done = 0;
    if (done)
        return;
    done = 1;
#ifdef OPENSSL_FIPS
    FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
# ifndef OPENSSL_NO_DEPRECATED
    FIPS_crypto_set_id_callback(CRYPTO_thread_id);
# endif
    FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
    FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
    RAND_init_fips();
    FIPS_mode_set(1);   <<< ENABLE FIPS MODE HERE <<<
#endif
#if 0
    fprintf(stderr, "Called OPENSSL_init\n");
#endif


However, I am sceptical whether this approach will be accepted, because there are (at least) two potential problems:

* Normally, it is mandatory to check the result of FIPS_mode_set() or FIPS_mode() to ensure that the FIPS initialization succeeded. However, an application which is not FIPS-aware won't check the result.
* It can happen that applications which have their own configuration and enable/disable FIPS mode explicitely, call FIPS_mode_set(0) afterwards.


HTH,
Matthias



--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Dr. Matthias St. Pierre


On 05.03.2018 11:57, Dr. Matthias St. Pierre wrote:

>
> However, I am sceptical whether this approach will be accepted,
> because there are (at least) two potential problems:
>
> * Normally, it is mandatory to check the result of FIPS_mode_set() or
> FIPS_mode() to ensure that the FIPS initialization succeeded. However,
> an application which is not FIPS-aware won't check the result.
> * It can happen that applications which have their own configuration
> and enable/disable FIPS mode explicitely, call FIPS_mode_set(0)
> afterwards.
>
>
> HTH,
> Matthias
>

One more obstacle: In FIPS mode it is not allowed to use low level
crypto algorithms, only the EVP interface is allowed. So most of your
non-fips-aware applications will malfunction when forced into FIPS mode.
The consequence is: it's probably not possible to do it.

Matthias

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Michael Richardson
In reply to this post by Dr. Matthias St. Pierre

Dr. Matthias St. Pierre <[hidden email]> wrote:
    > On 05.03.2018 10:46, Alan Dean wrote:
    >> Question 1: Is it even feasible to make the FIPS mode always enabled
    >> for the whole OpenSSL library (i.e. for both libcrypto and libssl), so

    > The optimal location for inserting the FIPS_mode_set(1) call is probably
    > OPENSSL_init()  (openssl-1.0.2/crypto/o_fips.c), see code snippet below.

    > void OPENSSL_init(void)
...

    > However, I am sceptical whether this approach will be accepted, because
    > there are (at least) two potential problems:

    > * Normally, it is mandatory to check the result of FIPS_mode_set() or
    > FIPS_mode() to ensure that the FIPS initialization succeeded. However,
    > an application which is not FIPS-aware won't check the result.

I think that Mr. Dean should check FIPS_mode_set() in OPENSSL_Init(), and
should probably do something like core dump if it fails to turn on properly.
Perhaps his system has a better way to get attention.

    > * It can happen that applications which have their own configuration and
    > enable/disable FIPS mode explicitely, call FIPS_mode_set(0) afterwards.

That should probably also cause a core dump.

Dr. Matthias St. Pierre <[hidden email]> wrote:
    > One more obstacle: In FIPS mode it is not allowed to use low level
    > crypto algorithms, only the EVP interface is allowed. So most of your
    > non-fips-aware applications will malfunction when forced into FIPS mode.
    > The consequence is: it's probably not possible to do it.

That should also cause a core dump.

At the end, Mr. Dean will have a much reduced list of applications that he
needs to either fix (sending patches upstream), or replace.
And the core dumps will point directly into the application code that made
the calls.

--
Michael Richardson <[hidden email]>, Sandelman Software Works
 -= IPv6 IoT consulting =-






--
]               Never tell me the odds!                 | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works        | network architect  [
]     [hidden email]  http://www.sandelman.ca/        |   ruby on rails    [


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

signature.asc (497 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Alan Dean
In reply to this post by Dr. Matthias St. Pierre
Thanks a lot Matthias for the suggestion.

I have few follow-up questions below:

On Mon, Mar 5, 2018 at 2:57 AM, Dr. Matthias St. Pierre <[hidden email]> wrote:



On 05.03.2018 10:46, Alan Dean wrote:
Question 1: Is it even feasible to make the FIPS mode always enabled for the whole OpenSSL library (i.e. for both libcrypto and libssl), so that most the applications which dynamically linked to libcrypto and libssl will be automatically use OpenSSL FIPS mode without the need of changes to add the FIPS_mode_set invocation (with some exception such as OpenSSH which may still need some fixes). (Assuming from certification's perspective we are ok if we may these changes)


Question 2: If the above idea is feasible, where in the OpenSSL library will be the best entry to invoke FIPS_mode_set API, so that we can make the whole OpenSSL library always in FIPS mode? Any potebtial issues for this solution?


Any suggestions will be greatly appreciated.



The optimal location for inserting the FIPS_mode_set(1) call is probably OPENSSL_init()  (openssl-1.0.2/crypto/o_fips.c), see code snippet below.

void OPENSSL_init(void)
{
    static int done = 0;
    if (done)
        return;
    done = 1;
#ifdef OPENSSL_FIPS
    FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
# ifndef OPENSSL_NO_DEPRECATED
    FIPS_crypto_set_id_callback(CRYPTO_thread_id);
# endif
    FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
    FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
    RAND_init_fips();
    FIPS_mode_set(1);   <<< ENABLE FIPS MODE HERE <<<
#endif
#if 0
    fprintf(stderr, "Called OPENSSL_init\n");
#endif

Currently OPENSSL_init() is actually invoked from within FIPS_mode_set(). If we put FIPS_mode_set() inside OPENSSL_init, then it makes OPENSSL_init to call itself recursively. In that case would it be ok to just remove OPENSSL_init from within FIPS_mode_set?

 


However, I am sceptical whether this approach will be accepted, because there are (at least) two potential problems:

* Normally, it is mandatory to check the result of FIPS_mode_set() or FIPS_mode() to ensure that the FIPS initialization succeeded. However, an application which is not FIPS-aware won't check the result.
Did you mean if FIPS_mode_set is invoked in the library level, then applications won't be checking the return results of FIPS_mode_set and could cause problem if FIPS_mode_set didn't finish successfully?

 
* It can happen that applications which have their own configuration and enable/disable FIPS mode explicitely, call FIPS_mode_set(0) afterwards.


HTH,
Matthias



--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users



--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Alan Dean
In reply to this post by Dr. Matthias St. Pierre


On Mon, Mar 5, 2018 at 3:04 AM, Dr. Matthias St. Pierre <[hidden email]> wrote:


On 05.03.2018 11:57, Dr. Matthias St. Pierre wrote:
>
> However, I am sceptical whether this approach will be accepted,
> because there are (at least) two potential problems:
>
> * Normally, it is mandatory to check the result of FIPS_mode_set() or
> FIPS_mode() to ensure that the FIPS initialization succeeded. However,
> an application which is not FIPS-aware won't check the result.
> * It can happen that applications which have their own configuration
> and enable/disable FIPS mode explicitely, call FIPS_mode_set(0)
> afterwards.
>
>
> HTH,
> Matthias
>

One more obstacle: In FIPS mode it is not allowed to use low level
crypto algorithms, only the EVP interface is allowed. So most of your
non-fips-aware applications will malfunction when forced into FIPS mode.
The consequence is: it's probably not possible to do it.
 
Did you mean if an application uses the low level crypto algorithm functions (e.g. SHA256_Init/ SHA256_Update/ SHA256_Final) then they won't work under FIPS mode (and hence may cause unpredictable issues)?


 

Matthias

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

OpenSSL - User mailing list
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Dr. Matthias St. Pierre

Am 05.03.2018 um 20:07 schrieb Salz, Rich via openssl-users:

>
>   * Did you mean if an application uses the low level crypto algorithm
>     functions (e.g. SHA256_Init/ SHA256_Update/ SHA256_Final) then
>     they won't work under FIPS mode (and hence may cause unpredictable
>     issues)?
>
>  
>
> Yes.
>
>  
>
> It’s not unpredictable issues, but rather that your application cannot
> claim to be FIPS validated.
>
>  
>
>
>

It's even worse: If you force an application which is not fips-aware
into FIPS mode and that application uses low level algorithms, then it
will be aborted by OpenSSL, because it is forbidden to use the low level
algorithms directly. To understand how this happens, search the source
code for 'fips_md_init' and 'fips_cipher_abort'. They are defined in
crypto.h, see end of mail.

Changing applications from the low level api is not a simple bugfix.
It's a nontrivial task.

So the situation is hopeless, I would say.

Matthias


crypto.h:
=======
# define fips_md_init(alg) fips_md_init_ctx(alg, alg)

# ifdef OPENSSL_FIPS
#  define fips_md_init_ctx(alg, cx) \
        int alg##_Init(cx##_CTX *c) \
        { \
        if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
                "Low level API call to digest " #alg " forbidden in FIPS
mode!"); \
        return private_##alg##_Init(c); \
        } \
        int private_##alg##_Init(cx##_CTX *c)

#  define fips_cipher_abort(alg) \
        if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
                "Low level API call to cipher " #alg " forbidden in FIPS
mode!")

# else
#  define fips_md_init_ctx(alg, cx) \
        int alg##_Init(cx##_CTX *c)
#  define fips_cipher_abort(alg) while(0)
# endif




--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Dr. Matthias St. Pierre
In reply to this post by Alan Dean

Am 05.03.2018 um 19:55 schrieb Alan Dean:
> Thanks a lot Matthias for the suggestion.
>
> I have few follow-up questions below:
>

Please see my other replies.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Alan Dean
Thanks Matthias for your response.

I have a different question:

Per your suggestion in the previous email, FIPS_mode_set() can be moved inside of OPENSSL_init(), in order to force the FIPS mode enabled in the library level.

However currently OPENSSL_init() is actually invoked from within FIPS_mode_set(). If we put FIPS_mode_set() inside OPENSSL_init, then it makes OPENSSL_init to call itself recursively. In that case would it be ok to just remove OPENSSL_init from within FIPS_mode_set?



On Mon, Mar 5, 2018 at 11:21 AM, Dr. Matthias St. Pierre <[hidden email]> wrote:

Am 05.03.2018 um 19:55 schrieb Alan Dean:
> Thanks a lot Matthias for the suggestion.
>
> I have few follow-up questions below:
>

Please see my other replies.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Enable the FIPS mode in the library level

Dr. Matthias St. Pierre

Am 05.03.2018 um 20:39 schrieb Alan Dean:

> Thanks Matthias for your response.
>
> I have a different question:
>
> Per your suggestion in the previous email, FIPS_mode_set() can be
> moved inside of OPENSSL_init(), in order to force the FIPS mode
> enabled in the library level.
>
> However currently OPENSSL_init() is actually invoked from within
> FIPS_mode_set(). If we put FIPS_mode_set() inside OPENSSL_init, then
> it makes OPENSSL_init to call itself recursively. In that case would
> it be ok to just remove OPENSSL_init from within FIPS_mode_set?
>

It is not a problem if OPENSSL_init() is reentered, because the 'done'
flag at the beginning of the function is set on first call to prevent
the body from being executed more than once. (Well, there is a potential
race condition if the first call to OPENSSL_init() happens concurrently,
but let's assume that on your first call to OPENSSL_init() your
application is still single-threaded.) So you can put the
FIPS_mode_set() call where I indicated without risking an infinite
recursion.

Having said that, I consider this change an interesting 'hack' if you
want to see what happens, but not more. I would like to emphasize once
more that it is a quite ambitious and almost impossible task to make all
these third party applications you were talking about conforming to the
FIPS regulations. Turning on FIPS mode is the smallest part of the
problem, you have to make the entire applications conform to the FIPS
rules. It's not only that you have to convert all the calls into low
level algorithms to using the EVP interface. Also, you have to prevent
the applications from using non-fipsed algorithms, like e.g. md5.  So in
many cases you will have to make deep changes to the application's logic.

Matthias


void OPENSSL_init(void)
{
    static int done = 0;
    if (done)
        return;
    done = 1;
#ifdef OPENSSL_FIPS
    FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
# ifndef OPENSSL_NO_DEPRECATED
    FIPS_crypto_set_id_callback(CRYPTO_thread_id);
# endif
    FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
    FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
    RAND_init_fips();
    FIPS_mode_set(1);   <<< ENABLE FIPS MODE HERE <<<
#endif
#if 0
    fprintf(stderr, "Called OPENSSL_init\n");
#endif

}


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users