CVE-2015-0204 (published 2015-01-09T02:59Z)

The ssl3_get_key_exchange function in s3_clnt.c in OpenSSL before 0.9.8zd, 1.0.0 before 1.0.0p, and 1.0.1 before 1.0.1k allows remote SSL servers to conduct RSA-to-EXPORT_RSA downgrade attacks and facilitate brute-force decryption by offering a weak ephemeral RSA key in a noncompliant role, related to the "FREAK" issue.  NOTE: the scope of this CVE is only client code based on OpenSSL, not EXPORT_RSA issues associated with servers or other TLS implementations.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:P/A:N)

Weakness information:
cwe_id: CWE-310
cwe_name: Cryptographic Issues
description: Weaknesses in this category are related to the design and implementation of data confidentiality and integrity. Frequently these deal with the use of encoding techniques, encryption libraries, and hashing algorithms. The weaknesses in this category could lead to a degradation of the quality data if they are not addressed.

Fix information:
repo_url: https://github.com/openssl/openssl
commit_details: repo_url: https://github.com/openssl/openssl
author: Dr. Stephen Henson
author_date: 2014-10-23 17:09:57+01:00
msg: Only allow ephemeral RSA keys in export ciphersuites.

OpenSSL clients would tolerate temporary RSA keys in non-export
ciphersuites. It also had an option SSL_OP_EPHEMERAL_RSA which
enabled this server side. Remove both options as they are a
protocol violation.

Thanks to Karthikeyan Bhargavan for reporting this issue.
(CVE-2015-0204)
Reviewed-by: Matt Caswell <matt@openssl.org>
repository: repo_url: https://github.com/openssl/openssl
repo_name: openssl/openssl
description: TLS/SSL and crypto library
repo_language: C
owner: openssl
file_changes: filename: CHANGES
change_type: ModificationType.MODIFY
diff: @@ -666,6 +666,14 @@
      (CVE-2014-3572)
      [Steve Henson]
 
+  *) Remove non-export ephemeral RSA code on client and server. This code
+     violated the TLS standard by allowing the use of temporary RSA keys in
+     non-export ciphersuites and could be used by a server to effectively
+     downgrade the RSA key length used to a value smaller than the server
+     certificate. Thanks for Karthikeyan Bhargavan for reporting this issue.
+     (CVE-2015-0204)
+     [Steve Henson]
+
   *) Ensure that the session ID context of an SSL is updated when its
      SSL_CTX is updated via SSL_set_SSL_CTX.
 

programming_language: Markdown
filename: SSL_CTX_set_options.pod
change_type: ModificationType.MODIFY
diff: @@ -151,15 +151,7 @@ temporary/ephemeral DH parameters are used.
 
 =item SSL_OP_EPHEMERAL_RSA
 
-Always use ephemeral (temporary) RSA key when doing RSA operations
-(see L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
-According to the specifications this is only done, when a RSA key
-can only be used for signature operations (namely under export ciphers
-with restricted RSA keylength). By setting this option, ephemeral
-RSA keys are always used. This option breaks compatibility with the
-SSL/TLS specifications and may lead to interoperability problems with
-clients and should therefore never be used. Ciphers with DHE (ephemeral
-Diffie-Hellman) key exchange should be used instead.
+This option is no longer implemented and is treated as no op.
 
 =item SSL_OP_CIPHER_SERVER_PREFERENCE
 

programming_language: Perl
filename: SSL_CTX_set_tmp_rsa_callback.pod
change_type: ModificationType.MODIFY
diff: @@ -74,21 +74,14 @@ exchange and use DHE (Ephemeral Diffie-Hellman) key exchange instead
 in order to achieve forward secrecy (see
 L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
 
-On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default
-and must be explicitly enabled  using the SSL_OP_EPHEMERAL_RSA option of
-L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, violating the TLS/SSL
-standard. When ephemeral RSA key exchange is required for export ciphers,
-it will automatically be used without this option!
-
-An application may either directly specify the key or can supply the key via
-a callback function. The callback approach has the advantage, that the
-callback may generate the key only in case it is actually needed. As the
-generation of a RSA key is however costly, it will lead to a significant
-delay in the handshake procedure.  Another advantage of the callback function
-is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
-usage) while the explicit setting of the key is only useful for key size of
-512 bits to satisfy the export restricted ciphers and does give away key length
-if a longer key would be allowed.
+An application may either directly specify the key or can supply the key via a
+callback function. The callback approach has the advantage, that the callback
+may generate the key only in case it is actually needed. As the generation of a
+RSA key is however costly, it will lead to a significant delay in the handshake
+procedure.  Another advantage of the callback function is that it can supply
+keys of different size while the explicit setting of the key is only useful for
+key size of 512 bits to satisfy the export restricted ciphers and does give
+away key length if a longer key would be allowed.
 
 The B<tmp_rsa_callback> is called with the B<keylength> needed and
 the B<is_export> information. The B<is_export> flag is set, when the

programming_language: Perl
filename: d1_srvr.c
change_type: ModificationType.MODIFY
diff: @@ -472,24 +472,15 @@ int dtls1_accept(SSL *s)
 		case SSL3_ST_SW_KEY_EXCH_B:
 			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
-			/* clear this, it may get reset by
-			 * send_server_key_exchange */
-			if ((s->options & SSL_OP_EPHEMERAL_RSA)
-#ifndef OPENSSL_NO_KRB5
-				&& !(alg_k & SSL_kKRB5)
-#endif /* OPENSSL_NO_KRB5 */
-				)
-				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
-				 * even when forbidden by protocol specs
-				 * (handshake may fail as clients are not required to
-				 * be able to handle this) */
-				s->s3->tmp.use_rsa_tmp=1;
-			else
-				s->s3->tmp.use_rsa_tmp=0;
+			/*
+			 * clear this, it may get reset by
+			 * send_server_key_exchange
+			 */
+			s->s3->tmp.use_rsa_tmp=0;
 
 			/* only send if a DH key exchange or
 			 * RSA but we have a sign only certificate */
-			if (s->s3->tmp.use_rsa_tmp
+			if (
 			/* PSK: send ServerKeyExchange if PSK identity
 			 * hint if provided */
 #ifndef OPENSSL_NO_PSK

programming_language: C
filename: s3_clnt.c
change_type: ModificationType.MODIFY
diff: @@ -1636,6 +1636,13 @@ int ssl3_get_key_exchange(SSL *s)
 #ifndef OPENSSL_NO_RSA
 	if (alg_k & SSL_kRSA)
 		{
+		/* Temporary RSA keys only allowed in export ciphersuites */
+		if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNEXPECTED_MESSAGE);
+			goto f_err;
+			}
 		if ((rsa=RSA_new()) == NULL)
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);

programming_language: C
filename: s3_srvr.c
change_type: ModificationType.MODIFY
diff: @@ -453,20 +453,11 @@ int ssl3_accept(SSL *s)
 		case SSL3_ST_SW_KEY_EXCH_B:
 			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
-			/* clear this, it may get reset by
-			 * send_server_key_exchange */
-			if ((s->options & SSL_OP_EPHEMERAL_RSA)
-#ifndef OPENSSL_NO_KRB5
-				&& !(alg_k & SSL_kKRB5)
-#endif /* OPENSSL_NO_KRB5 */
-				)
-				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
-				 * even when forbidden by protocol specs
-				 * (handshake may fail as clients are not required to
-				 * be able to handle this) */
-				s->s3->tmp.use_rsa_tmp=1;
-			else
-				s->s3->tmp.use_rsa_tmp=0;
+			/*
+			 * clear this, it may get reset by
+			 * send_server_key_exchange
+			 */
+			s->s3->tmp.use_rsa_tmp=0;
 
 
 			/* only send if a DH key exchange, fortezza or
@@ -480,7 +471,7 @@ int ssl3_accept(SSL *s)
 			 * server certificate contains the server's
 			 * public key for key exchange.
 			 */
-			if (s->s3->tmp.use_rsa_tmp
+			if (
 			/* PSK: send ServerKeyExchange if PSK identity
 			 * hint if provided */
 #ifndef OPENSSL_NO_PSK

programming_language: C
filename: ssl.h
change_type: ModificationType.MODIFY
diff: @@ -606,9 +606,8 @@ struct ssl_session_st
 #define SSL_OP_SINGLE_ECDH_USE				0x00080000L
 /* If set, always create a new key when using tmp_dh parameters */
 #define SSL_OP_SINGLE_DH_USE				0x00100000L
-/* Set to always use the tmp_rsa key when doing RSA operations,
- * even when this violates protocol specs */
-#define SSL_OP_EPHEMERAL_RSA				0x00200000L
+/* Does nothing: retained for compatibiity */
+#define SSL_OP_EPHEMERAL_RSA				0x0
 /* Set on servers to choose the cipher according to the server's
  * preferences */
 #define SSL_OP_CIPHER_SERVER_PREFERENCE			0x00400000L

programming_language: C