summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--ssl/s3_clnt.c8
-rw-r--r--ssl/s3_lib.c139
-rw-r--r--ssl/ssl.h1
-rw-r--r--ssl/ssl_ciph.c25
-rw-r--r--ssl/ssl_lib.c4
-rw-r--r--ssl/ssl_locl.h8
-rw-r--r--ssl/tls1.h22
8 files changed, 206 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index cf52b0f3f7..bd97fedda9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
Changes between 1.0.0e and 1.0.1 [xx XXX xxxx]
+ *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support.
+ As required by RFC5289 these ciphersuites cannot be used if for
+ versions of TLS earlier than 1.2.
+ [Steve Henson]
+
*) For FIPS capable OpenSSL interpret a NULL default public key method
as unset and return the appopriate default but do *not* set the default.
This means we can return the appopriate method in applications that
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index dd9a5c2864..22be653f59 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -876,6 +876,14 @@ int ssl3_get_server_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);
goto f_err;
}
+ /* TLS v1.2 only ciphersuites require v1.2 or later */
+ if ((c->algorithm_ssl & SSL_TLSV1_2) &&
+ (TLS1_get_version(s) < TLS1_2_VERSION))
+ {
+ al=SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
+ goto f_err;
+ }
p+=ssl_put_cipher_by_char(s,NULL,NULL);
sk=ssl_get_ciphers_by_id(s);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 43799202dd..9b4703686e 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2370,6 +2370,140 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
256,
},
#endif /* OPENSSL_NO_SRP */
+#ifndef OPENSSL_NO_ECDH
+
+ /* HMAC based TLS v1.2 ciphersuites from RFC5289 */
+
+ /* Cipher C023 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
+ SSL_kEECDH,
+ SSL_aECDSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C024 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
+ SSL_kEECDH,
+ SSL_aECDSA,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C025 */
+ {
+ 1,
+ TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C026 */
+ {
+ 1,
+ TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C027 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
+ SSL_kEECDH,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C028 */
+ {
+ 1,
+ TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
+ SSL_kEECDH,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+ /* Cipher C029 */
+ {
+ 1,
+ TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ 128,
+ 128,
+ },
+
+ /* Cipher C02A */
+ {
+ 1,
+ TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384,
+ TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384,
+ SSL_kECDHe,
+ SSL_aECDH,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_TLSV1_2,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ 256,
+ 256,
+ },
+
+#endif /* OPENSSL_NO_ECDH */
+
#ifdef TEMP_GOST_TLS
/* Cipher FF00 */
@@ -3298,6 +3432,11 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
{
c=sk_SSL_CIPHER_value(prio,i);
+ /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
+ if ((c->algorithm_ssl & SSL_TLSV1_2) &&
+ (TLS1_get_version(s) < TLS1_2_VERSION))
+ continue;
+
ssl_set_cert_masks(cert,c);
mask_k = cert->mask_k;
mask_a = cert->mask_a;
diff --git a/ssl/ssl.h b/ssl/ssl.h
index f5e6cc00e9..6af291ba83 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -297,6 +297,7 @@ extern "C" {
#define SSL_TXT_GOST94 "GOST94"
#define SSL_TXT_GOST89MAC "GOST89MAC"
#define SSL_TXT_SHA256 "SHA256"
+#define SSL_TXT_SHA384 "SHA384"
#define SSL_TXT_SSLV2 "SSLv2"
#define SSL_TXT_SSLV3 "SSLv3"
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index b0542d1b4a..224c63db77 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -180,28 +180,31 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
#define SSL_MD_GOST94_IDX 2
#define SSL_MD_GOST89MAC_IDX 3
#define SSL_MD_SHA256_IDX 4
+#define SSL_MD_SHA384_IDX 5
/*Constant SSL_MAX_DIGEST equal to size of digests array should be
* defined in the
* ssl_locl.h */
#define SSL_MD_NUM_IDX SSL_MAX_DIGEST
static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
- NULL,NULL,NULL,NULL,NULL
+ NULL,NULL,NULL,NULL,NULL,NULL
};
/* PKEY_TYPE for GOST89MAC is known in advance, but, because
* implementation is engine-provided, we'll fill it only if
* corresponding EVP_PKEY_METHOD is found
*/
static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
- EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef,EVP_PKEY_HMAC
+ EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef,
+ EVP_PKEY_HMAC,EVP_PKEY_HMAC
};
static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={
- 0,0,0,0,0
+ 0,0,0,0,0,0
};
static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={
SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA,
- SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256
+ SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256,
+ SSL_HANDSHAKE_MAC_SHA384
};
#define CIPHER_ADD 1
@@ -300,6 +303,7 @@ static const SSL_CIPHER cipher_aliases[]={
{0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0},
{0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0},
{0,SSL_TXT_SHA256,0, 0,0,0,SSL_SHA256, 0,0,0,0,0},
+ {0,SSL_TXT_SHA384,0, 0,0,0,SSL_SHA384, 0,0,0,0,0},
/* protocol version aliases */
{0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0},
@@ -412,6 +416,10 @@ void ssl_load_ciphers(void)
EVP_get_digestbyname(SN_sha256);
ssl_mac_secret_size[SSL_MD_SHA256_IDX]=
EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]);
+ ssl_digest_methods[SSL_MD_SHA384_IDX]=
+ EVP_get_digestbyname(SN_sha384);
+ ssl_mac_secret_size[SSL_MD_SHA384_IDX]=
+ EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]);
}
#ifndef OPENSSL_NO_COMP
@@ -559,6 +567,9 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
case SSL_SHA256:
i=SSL_MD_SHA256_IDX;
break;
+ case SSL_SHA384:
+ i=SSL_MD_SHA384_IDX;
+ break;
case SSL_GOST94:
i = SSL_MD_GOST94_IDX;
break;
@@ -731,6 +742,7 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
*mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
*mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
*mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256:0;
+ *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384:0;
*mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0;
*mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0;
@@ -1524,6 +1536,8 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
ver="SSLv2";
else if (alg_ssl & SSL_SSLV3)
ver="SSLv3";
+ else if (alg_ssl & SSL_TLSV1_2)
+ ver="TLSv1.2";
else
ver="unknown";
@@ -1646,6 +1660,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_SHA256:
mac="SHA256";
break;
+ case SSL_SHA384:
+ mac="SHA384";
+ break;
default:
mac="unknown";
break;
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 2cd78c13cc..65a515753e 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1366,6 +1366,10 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
{
c=sk_SSL_CIPHER_value(sk,i);
+ /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
+ if ((c->algorithm_ssl & SSL_TLSV1_2) &&
+ (TLS1_get_version(s) < TLS1_2_VERSION))
+ continue;
#ifndef OPENSSL_NO_KRB5
if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) &&
nokrb5)
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 65a3639a44..983ddaf609 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -328,11 +328,13 @@
#define SSL_GOST94 0x00000004L
#define SSL_GOST89MAC 0x00000008L
#define SSL_SHA256 0x00000010L
+#define SSL_SHA384 0x00000020L
/* Bits for algorithm_ssl (protocol version) */
#define SSL_SSLV2 0x00000001L
#define SSL_SSLV3 0x00000002L
#define SSL_TLSV1 SSL_SSLV3 /* for now */
+#define SSL_TLSV1_2 0x00000004L
/* Bits for algorithm2 (handshake digests and other extra flags) */
@@ -341,18 +343,20 @@
#define SSL_HANDSHAKE_MAC_SHA 0x20
#define SSL_HANDSHAKE_MAC_GOST94 0x40
#define SSL_HANDSHAKE_MAC_SHA256 0x80
+#define SSL_HANDSHAKE_MAC_SHA384 0x100
#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
* make sure to update this constant too */
-#define SSL_MAX_DIGEST 5
+#define SSL_MAX_DIGEST 6
#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_DGST_SHIFT 8
+#define TLS1_PRF_DGST_SHIFT 10
#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT)
#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
diff --git a/ssl/tls1.h b/ssl/tls1.h
index 1246e4adef..e7e82601f5 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -436,6 +436,17 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021
#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026
+#define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027
+#define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028
+#define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029
+#define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A
+
/* XXX
* Inconsistency alert:
* The OpenSSL names of ciphers with ephemeral DH here include the string
@@ -552,6 +563,17 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256"
#define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256"
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384"
+
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2
#define TLS_CT_RSA_FIXED_DH 3