The new SP800-131A and FIPS 186-4 restrictions on algorithms and key sizes complicate
the use of ciphersuites for TLS considerably. This page is intended to answer the
question "can I configure an OpenSSL cipherstring for TLS to comply with the new FIPS restrictions?".

This discussion assumes use of a "FIPS capable" OpenSSL 1.0.1f or later.

A new security framework in development for future versions will make enforcing these types
of restrictions easier and the algorithm restrictions are performed all in one place.

The cipherstring notation is discussed at https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
Briefly, a cipherstring is a series of elements each designating either a specific ciphersuite or a set of
ciphersuites. The "+" operator designates a logical and operation, so "element1+element1" represents that
set of ciphersuites containing the algorithms in both element1 and element2. The "!" operator permanently
all the algorithms in the following element.

All TLS 1.0/1.1 authenticated PFS (Perfect Forward Secrecy) ciphersuites use SHA1 alone or MD5+SHA1. That
leaves only unauthenticated ones (which are vulnerable to MiTM so we discount
them) or those using static keys. Theoretically that would permit RSA, DH or
ECDH keys in certificates but in practice everyone uses RSA.

That cipherstring specifies three possible ciphersuites allowable in FIPS mode for TLS 1.0 and 1.1.
The RSA key in the certificate has to be of suitable size
(2048 bits minimum) as do all other keys in the chain and none of the CAs can
sign using SHA1. Also those kRSA ciphersuites are allowed for
server certificates only; client authentication is never allowed
with the new rules for TLS 1.0 and 1.1.

In a real application when FIPS mode is enabled then only
FIPS ciphersuites are allowed no matter what you use in the string. So in FIPS mode
"kRSA:!TLSv1.2" will be functionally equivalent to "kRSA+FIPS!TLSv1.2".

Note the "TLSv1.2" string was only added to OpenSSL recently, as of OpenSSL 1.0.1f.
It designates the ciphers for TLSv1.2 subject to the FIPS 140-2 and FIPS 186-4
restrictions.

Note the cipherstring 'FIPS:!TLSv1.2' would also allow fixed DH and fixed ECDH
certificates but those are not encountered in the wild.
The key exchange component "kRSA" specifies just those algorithms that support RSA key exchange.

TLS 1.2 provides more options as the signature can use an algorithm other
than SHA1.
"kRSA+FIPS" specifies those ciphersuites that use RSA key exchange, including TLS v1.2, *and*
are allowed in FIPS mode, and including anonymous ones which may be undesirable:

The ephemeral key for the now permitted PFS keys must be at least 2048 bits (DH)
or 256 bits (ECDH) in size. Anything supporting ECDH will probably set P-256 as
a default so that should be OK (Apache does).

There's a snag though. The ciphersuite ECDH-RSA-AES128-SHA can (outside FIPS) be
used for TLS 1.0 and later whereas in FIPS mode it can only be used for TLS v1.2. A
TLS client can't advertise ciphersuites in that way (i.e. you can use this for
TLS1.2 only and nothing earlier) so you're left with the situation where a FIPS
compliant client might say it wants ECDH-RSA-AES128-SHA
and TLS 1.2 and the server only supports TLS 1.0 so it will choke when it tries to
use the prohibited ciphersuite+version combination. Servers are fine because
they can theoretically select based on version (except in practice OpenSSL doesn't support that).

If that wasn't enough there's another complication. For TLS v1.2 you have to
restrict the supported signature algorithms to exclude SHA1, allowing only
SHA256 and above. There is no way to do that in OpenSSL 1.0.1 clients.
Similarly the supported EC curves have to be restricted to exclude some which are
of insufficient field size.

In summary: it's a bloody mess.

The list of allowable ciphers for all versions of TLS, 1.0/1/1/1.2 is 'TLSv1.2:kRSA'
which includes those with no encryption or no authentication which are generally
undesirable and should be excluded. In full with explicit "+FIPS" qualification that becomes:

Commentary on what the cipherstrings components mean and their relevance:

"TLSv1.2": list of ciphersuites only allowed for TLS 1.2. This means if TLS 1.2
is negotiated they can be used and if not they won't. They also happen to be
permitted by FIPS 186-4 because TLS 1.2 can use signature algorithms stronger
that SHA1. That means that it is "safe" to include this in a cipher string
because (a) they are compliant with FIPS 186-4 in for TLS 1.2 and (b) they can
never be used for TLS 1.1 or 1.0.

"kRSA": list of ciphersuites which support RSA key exchange. Because TLS 1.1 and
1.0 can only use SHA1+MD5 in signatures these are the only ones allowed because
they don't use signatures.

"FIPS": list of ciphersuites allowed in FIPS mode excluding those offering no
encryption. This is for informational purposes only because if you *are* in FIPS
mode you can only use those ciphersuites anyway (but including the no encryption
ones).

The lists above all include ciphersuites which you wouldn't normally use: no
encryption or no authentication. So those need to be disabled. This is done by
appending '!eNULL:!aNULL': this means "disable any ciphersuites present which
include no encryption or authentication".

So combining these we get the following cipher string in FIPS mode:

'TLSv1.2:kRSA:!eNULL:!aNULL'

which with the functionally redundant "+FIPS" qualifiers is equivant to:

'TLSv1.2+FIPS:kRSA+FIPS:!eNULL:!aNULL'

Without the "+FIPS" qualifiers and outside FIPS mode you'll will see weak export grade
ciphersuites which would be disabled in FIPS mode. Those can be seen with:

openssl ciphers -v 'TLSv1.2:kRSA:!eNULL:!aNULL'

To see the actual set of ciphersuites in FIPS mode, without the explicit "+FIPS" qualifiers,
do:

OPENSSL_FIPS=1 openssl ciphers -v 'TLSv1.2:kRSA:!eNULL:!aNULL'

So in summary "in FIPS mode use the cipherstring 'TLSv1.2:kRSA:!eNULL:!aNULL'"

Note this important disclaimer though: This cipherstring *only* restricts the ciphersuites to those
not explicitly excluded by FIPS 186-4. There are other conditions which must be
enforced such as key size, permitted curves and permitted signature algorithms.
Just because a ciphersuite has been negotiated in this range does not guaranteed
compliance.

The "FIPS capable" OpenSSL does not currently provide a means to automatically enforce the
new FIPS 186-4 restrictions.

The primary purpose of the handshake is to enable both peers to securely obtain
a shared secret value called the pre-master secret. They then use that to
generate session keys (encryption and MAC) which are used for the exchange of
actual application data. The handshake is the only place public key algorithms
are used.

In the case of PFS ciphersuites both ends generate a temporary key (ECDH or DH)
and exchange the public bits with each other. They use the algorithm to generate
the shared DH/ECDH secret value which is used later on. The new FIPS restrictions interfere with
this because those keys have to be large enough. For ECDH an extension can be
used to ensure this. For DH you just have to hope the server has a big enough
key and abort if not.

For anonymous algorithms that's all you get. They are vulnerable to man in the
middle (MitM) attacks and so are rarely used.

In the real world algorithms include authentication. In those the server digitally
signs its ECDH or DH key using the key in its certificate. This is to ensure the
temporary ECDH or DH key can't be forged. It is that digital signature that is
important here and the one which the new FIPS restrictions disrupt.

How that temporary key is signed depends on the cipher suite and the key in the
server's certificate. The whole process is called server authentication.

In the case of TLS 1.0 and 1.1 that signature uses a MD5+SHA1 hybrid for RSA
keys and just SHA1 for DSA and ECDSA. That's why PFS is prohibited by the new FIPS
rules: there is no option but to use SHA1.

In the case of TLS 1.2 any valid combination can be used and the MD5+SHA1 hybrid is no
longer present for RSA. RSA just uses the same signature format that
certificates use (PKCS#1).

For TLS 1.2 the client sends the set of signature algorithms it supports in
preference order in the supported signature algorithms extensions. The server
then selects one and uses that for that signature. For new FIPS it would just
use SHA256 as a minimum or abort the connection if the client only supported
SHA1 (unlikely).

Client authentication in TLS is a secondary concern. In this case the client
signs some data related to the handshake and sends the result back. The server
then checks that signature.

As with server authentication TLS 1.1/1.0 has to use either MD5+SHA1 for RSA or
just SHA1 for other algorithms. So client authentication violates the new FIPS
restrictions and cannot be used for TLs 1.0/1.1.

TLS 1.2 removes the restriction to SHA1. In this case the server sends back the
algorithms it supports and the client selects one. Again SHA256 or
better s needed to comply with new FIPS restrictions.

Next consider the non-PFS case. We consider RSA
key exchange only as is the only practical option. This is completely different from PFS. In
this case the client generates the pre master secret and encrypts it using the
servers key. The server decrypts it and then uses that to complete the
handshake. No additional signing is used here so no place for SHA1 to be used.
The server is authenticated because if it didn't have the right key it couldn't
decrypt the pre-master secret. It's a bit unusual in that authentication (which
is normally associated with signatures) is performed using an RSA decryption
operation.

Some further discussion in case that wasn't confusing enough:

Some people say that it is implied that TLS 1.1 and 1.0 must use SHA1 in
digital signatures in all certificates. If so then
TLS 1.1 and 1.0 can never be compliant with new FIPS.

Assuming that is not true, what does it mean in practice? A
a public webserver would require a certificate signed by CAs that
use SHA256 minimum and large enough keys. Not a trivial
task in itself.

Aside from that, problems will be encountered if your server needs to use anything
outside of the new FIPS restrictions (e.g. to talk to other
clients). Some older browsers (e.g. IE on XP is one which is
still very common) don't support SHA2 at all. So they'll fail when they talk to
that server because the can't verify the signatures.

TLS 1.2 is a bit better, at least in theory. The supported signatures should apply to the
whole certificate chain. So a client advertising only SHA1+RSA receive a
chain supporting SHA1+RSA only (if the server has one) and a client supporting SHA256+RSA
will receive a "new FIPS" friendly chain.

However, in practice that requirement is generally ignored and implementations serve up whatever
chain is configured regardless of signature algorithms sent by the client
because many implementers consider that a slly restriction. For interoperability OpenSSL is
similarly lax if a "strict" option isn't set. In fact configuring multiple
chains like that can't be directly done in OpenSSL without application support
which nothing other than s_server can currently handle.

In TLS 1.2 something called the supported signature algorithms extension
determines the supported digests as a public key + algorithm pair. It's that
usage that FIPS 186-4 (and SP800-57) has an impact on. So you can't use RSA+SHA1
any more. For digital signatures the strength of SHA1 is at most 80 bits: it can
be less with a weak key.

That digital signature is used to maintain the integrity of the handshake
messages and certificate chains in PFS ciphersuites: basically server and client
authentication.

For TLS 1.2 you can specify any digest to be used to maintain handshake
integrity for digital signatures: for TLS 1.1 and below you could only use
SHA1+MD5. It's that reason why PFS ciphersuites are banned in TLS 1.1 and below.

Digests use HMAC. For HMAC use the key strength is the digest length so SHA1 is 160 bits.

Before TLS 1.2 all cipher suites used SHA1 HMAC (or in legacy cases MD5) for the
HMAC.

TLS 1.2 introduced some ciphersuites which used SHA256 and SHA384 for the HMAC
and the AEAD ones like AES-GCM which have a mac as part of the algorithm itself.

Note that TLS 1.2 also permits all the ciphersuites for TLS 1.1, 1.0 too.
For details see Table 2 and 3 in SP800-57.

Those tables make a lot more sense when you realise for digital signatures it's
half the digest size. So SHA1 is 20 bytes which is 160 bits and so 80 bits of
strength so it only appears in the "80 bits" box for digital signatures. Whereas
for other uses it is the full digest size so SHA1 appears in the 80, 112 and 128
bit boxes.

Unfortunately the FIPS terminology unnecessarily obfuscated the issue. It would
have been easier to just say in SP800-57 that SHA1 HMAC is 160 bits
of equivalent security instead of placing it in the :Security Strenght 128" row
of Table 3.

TLS 1.2 can use SHA1 in two different places. One is the signature algorithms on
certificates: i.e. the algorithm the CA signs with. The second place is
temporary key signature (server authentication) as described below.

The certificates' signatures are set by the CA so to comply with new FIPS
whatever else you do you need a certificate chain that uses SHA256 at least.

2. Server Key Exchange.

The Server Key Exchange message contains a signature in any authenticated PFS
ciphersuite. The algorithm used depends on the version of TLS.

For TLS 1.1 and 1.0 the algorithm is either a MD5+SHA1 hybrid (RSA) or SHA1
(DSA, ECDSA). Both of these are prohibited by new FIPS so TLS 1.1 and 1.0
authenticated PFS ciphersuites are not allowed.

For TLS 1.2 any appropriate algorithm can be used to sign Server Key Exchange
messages. So PFS authenticated ciphersuites *are* allowed under new FIPS as long
as SHA1 is not used to sign Server Key Exchange. MD5 is of course a double no-no.

3. Certificate Verify.

The Certificate Verify message is used whenever client authentication is enabled
for any applicable ciphersuite (not just PFS). The same digest algorithms are
used as Server Key Exchange.

However, as new ciphersuites get added to the 'TLSv1.2' ciphersuite that brute force
equivalent might end up not being
equivalent any more.

Since TLSv1.2 only ciphers use SHA256, SHA384 and AES in GCM mode so one string is:

'AESGCM:SHA384:SHA256'

There are other ways to get the same effect. One is to disable any ciphers which
use SHA1. So "FIPS:-SHA" is currently equivalent to "FIPS+TLSv1.2". The use of
the "-SHA" is necessary here because it only *temporarily* disables SHA1 MACs.
That means you can do: "FIPS:-SHA:FIPS+kRSA" to add back the RSA key exchange
ciphersuites that use SHA1. Contrast that with using "!SHA" instead which permanently
removes SHA1 from the cipherstring.