diff options
author | Elio Maldonado <emaldona@redhat.com> | 2016-05-19 18:44:01 +0200 |
---|---|---|
committer | Elio Maldonado <emaldona@redhat.com> | 2016-05-19 18:44:01 +0200 |
commit | f9f47c24b4072415b4e7fa935998429ae1e1e902 (patch) | |
tree | 58265b9e1a4fc63b4143b019f3e501c7d81d23ad | |
parent | 2d407ee533f68d19ff90abd4da37c7cc8a74afc2 (diff) | |
download | nss-hg-f9f47c24b4072415b4e7fa935998429ae1e1e902.tar.gz |
Bug 923089, Support TLS 1.2 PRF with SHA-384 as the hash function. Patch by Elio. Some improvements by Martin that have r=kaie. Some fixes and changes requested by reviewer by Kai. Overall r=martin.thomson
-rw-r--r-- | external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc | 9 | ||||
-rw-r--r-- | lib/softoken/pkcs11c.c | 2 | ||||
-rw-r--r-- | lib/ssl/ssl3con.c | 431 | ||||
-rw-r--r-- | lib/ssl/ssl3ecc.c | 8 | ||||
-rw-r--r-- | lib/ssl/sslenum.c | 16 | ||||
-rw-r--r-- | lib/ssl/sslimpl.h | 7 | ||||
-rw-r--r-- | lib/ssl/sslinfo.c | 9 | ||||
-rw-r--r-- | lib/ssl/sslproto.h | 7 | ||||
-rw-r--r-- | lib/ssl/sslt.h | 3 | ||||
-rw-r--r-- | lib/ssl/tls13con.c | 77 | ||||
-rw-r--r-- | lib/ssl/tls13hkdf.c | 5 | ||||
-rwxr-xr-x | tests/ssl/ssl.sh | 11 | ||||
-rw-r--r-- | tests/ssl/sslcov.txt | 7 |
13 files changed, 377 insertions, 215 deletions
diff --git a/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc b/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc index f6a00efde..d69cca935 100644 --- a/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc +++ b/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc @@ -105,11 +105,18 @@ INSTANTIATE_CIPHER_TEST_P(RC4, Stream, V10ToV12, INSTANTIATE_CIPHER_TEST_P(AEAD12, All, V12, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - TLS_DHE_RSA_WITH_AES_128_GCM_SHA256); + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384); INSTANTIATE_CIPHER_TEST_P(AEAD, All, V12Plus, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256); INSTANTIATE_CIPHER_TEST_P(CBC12, All, V12, diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c index d398e8462..59b370a61 100644 --- a/lib/softoken/pkcs11c.c +++ b/lib/softoken/pkcs11c.c @@ -6084,7 +6084,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, int i; unsigned int outLen; unsigned char sha_out[SHA1_LENGTH]; - unsigned char key_block[NUM_MIXERS * MD5_LENGTH]; + unsigned char key_block[NUM_MIXERS * SFTK_MAX_MAC_LENGTH]; unsigned char key_block2[MD5_LENGTH]; PRBool isFIPS; HASH_HashType hashType; diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index c9786aafe..1fdf4c947 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -107,6 +107,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around * bug 946147. */ @@ -116,6 +118,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, @@ -125,6 +129,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,SSL_ALLOWED,PR_TRUE, PR_FALSE}, { TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, @@ -154,6 +160,7 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { /* RSA */ { TLS_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_RSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, @@ -204,6 +211,7 @@ static const SSLSignatureAndHashAlg defaultSignatureAlgorithms[] = { { ssl_hash_sha512, ssl_sign_ecdsa }, { ssl_hash_sha1, ssl_sign_ecdsa }, #endif + { ssl_hash_sha384, ssl_sign_dsa }, { ssl_hash_sha256, ssl_sign_dsa }, { ssl_hash_sha1, ssl_sign_dsa } }; @@ -302,6 +310,7 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = { {cipher_camellia_256, calg_camellia, 32,32, type_block, 16,16, 0, 0, SEC_OID_CAMELLIA_256_CBC}, {cipher_seed, calg_seed, 16,16, type_block, 16,16, 0, 0, SEC_OID_SEED_CBC}, {cipher_aes_128_gcm, calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8, SEC_OID_AES_128_GCM}, + {cipher_aes_256_gcm, calg_aes_gcm, 32,32, type_aead, 4, 0,16, 8, SEC_OID_AES_256_GCM}, {cipher_chacha20, calg_chacha20, 32,32, type_aead, 12, 0,16, 0, SEC_OID_CHACHA20_POLY1305}, {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0, 0}, }; @@ -338,145 +347,154 @@ static const ssl3KEADef kea_defs[] = /* must use ssl_LookupCipherSuiteDef to access */ static const ssl3CipherSuiteDef cipher_suite_defs[] = { -/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg */ +/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg prf_hash_alg */ +/* Note that the prf_hash_alg is the hash function used by the PRF, see sslimpl.h. */ - {TLS_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null}, - {TLS_RSA_WITH_NULL_MD5, cipher_null, mac_md5, kea_rsa}, - {TLS_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_rsa}, - {TLS_RSA_WITH_NULL_SHA256, cipher_null, hmac_sha256, kea_rsa}, - {TLS_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export}, - {TLS_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, kea_rsa}, - {TLS_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_rsa}, + {TLS_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null, ssl_hash_none}, + {TLS_RSA_WITH_NULL_MD5, cipher_null, mac_md5, kea_rsa, ssl_hash_none}, + {TLS_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_rsa, ssl_hash_none}, + {TLS_RSA_WITH_NULL_SHA256, cipher_null, hmac_sha256, kea_rsa, ssl_hash_sha256}, + {TLS_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export, ssl_hash_none}, + {TLS_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, kea_rsa, ssl_hash_none}, + {TLS_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_rsa, ssl_hash_none}, {TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, - cipher_rc2_40, mac_md5, kea_rsa_export}, + cipher_rc2_40, mac_md5, kea_rsa_export, ssl_hash_none}, #if 0 /* not implemented */ - {TLS_RSA_WITH_IDEA_CBC_SHA, cipher_idea, mac_sha, kea_rsa}, + {TLS_RSA_WITH_IDEA_CBC_SHA, cipher_idea, mac_sha, kea_rsa, ssl_hash_none}, {TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, - cipher_des40, mac_sha, kea_rsa_export}, + cipher_des40, mac_sha, kea_rsa_export, ssl_hash_none}, #endif - {TLS_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa}, - {TLS_DHE_DSS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_dss}, + {TLS_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa, ssl_hash_none}, + {TLS_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa, ssl_hash_none}, + {TLS_DHE_DSS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_dss, ssl_hash_none}, {TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, - cipher_3des, mac_sha, kea_dhe_dss}, - {TLS_DHE_DSS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_dhe_dss}, + cipher_3des, mac_sha, kea_dhe_dss, ssl_hash_none}, + {TLS_DHE_DSS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_dhe_dss, ssl_hash_none}, #if 0 /* not implemented */ {TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, - cipher_des40, mac_sha, kea_dh_dss_export}, - {TLS_DH_DSS_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_dss}, - {TLS_DH_DSS_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_dss}, + cipher_des40, mac_sha, kea_dh_dss_export, ssl_hash_none}, + {TLS_DH_DSS_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_dss, ssl_hash_none}, + {TLS_DH_DSS_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_dss, ssl_hash_none}, {TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, - cipher_des40, mac_sha, kea_dh_rsa_export}, - {TLS_DH_RSA_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa}, - {TLS_DH_RSA_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_rsa}, + cipher_des40, mac_sha, kea_dh_rsa_export, ssl_hash_none}, + {TLS_DH_RSA_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa, ssl_hash_none}, + {TLS_DH_RSA_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_rsa, ssl_hash_none}, {TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, - cipher_des40, mac_sha, kea_dh_dss_export}, + cipher_des40, mac_sha, kea_dh_dss_export, ssl_hash_none}, {TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, - cipher_des40, mac_sha, kea_dh_rsa_export}, + cipher_des40, mac_sha, kea_dh_rsa_export, ssl_hash_none}, #endif - {TLS_DHE_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_rsa}, + {TLS_DHE_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_rsa, ssl_hash_none}, {TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_3des, mac_sha, kea_dhe_rsa}, + cipher_3des, mac_sha, kea_dhe_rsa, ssl_hash_none}, #if 0 - {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export}, + {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export, ssl_hash_none}, {TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, - cipher_des40, mac_sha, kea_dh_anon_export}, - {TLS_DH_anon_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_anon}, - {TLS_DH_anon_WITH_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_anon}, + cipher_des40, mac_sha, kea_dh_anon_export, ssl_hash_none}, + {TLS_DH_anon_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_anon, ssl_hash_none}, + {TLS_DH_anon_WITH_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_anon, ssl_hash_none}, #endif /* New TLS cipher suites */ - {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa}, - {TLS_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_rsa}, - {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_dss}, - {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_rsa}, - {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_rsa}, - {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_rsa}, - {TLS_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_rsa}, - {TLS_DHE_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_dss}, - {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_rsa}, - {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_rsa}, + {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa, ssl_hash_none}, + {TLS_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_rsa, ssl_hash_sha256}, + {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_dss, ssl_hash_none}, + {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_rsa, ssl_hash_none}, + {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_rsa, ssl_hash_sha256}, + {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_rsa, ssl_hash_none}, + {TLS_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_rsa, ssl_hash_sha256}, + {TLS_DHE_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_dss, ssl_hash_none}, + {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_rsa, ssl_hash_none}, + {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_rsa, ssl_hash_sha256}, + {TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_dhe_rsa, ssl_hash_sha384}, #if 0 - {TLS_DH_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_dss}, - {TLS_DH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_rsa}, - {TLS_DH_anon_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_anon}, - {TLS_DH_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_dss}, - {TLS_DH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_rsa}, - {TLS_DH_anon_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_anon}, + {TLS_DH_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_dss, ssl_hash_none}, + {TLS_DH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_rsa, ssl_hash_none}, + {TLS_DH_anon_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_anon, ssl_hash_none}, + {TLS_DH_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_dss, ssl_hash_none}, + {TLS_DH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_rsa, ssl_hash_none}, + {TLS_DH_anon_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_anon, ssl_hash_none}, #endif - {TLS_RSA_WITH_SEED_CBC_SHA, cipher_seed, mac_sha, kea_rsa}, + {TLS_RSA_WITH_SEED_CBC_SHA, cipher_seed, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, cipher_camellia_128, mac_sha, kea_rsa}, + {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, cipher_camellia_128, mac_sha, kea_rsa, ssl_hash_none}, {TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - cipher_camellia_128, mac_sha, kea_dhe_dss}, + cipher_camellia_128, mac_sha, kea_dhe_dss, ssl_hash_none}, {TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - cipher_camellia_128, mac_sha, kea_dhe_rsa}, - {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, cipher_camellia_256, mac_sha, kea_rsa}, + cipher_camellia_128, mac_sha, kea_dhe_rsa, ssl_hash_none}, + {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, cipher_camellia_256, mac_sha, kea_rsa, ssl_hash_none}, {TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - cipher_camellia_256, mac_sha, kea_dhe_dss}, + cipher_camellia_256, mac_sha, kea_dhe_dss, ssl_hash_none}, {TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - cipher_camellia_256, mac_sha, kea_dhe_rsa}, + cipher_camellia_256, mac_sha, kea_dhe_rsa, ssl_hash_none}, {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, - cipher_des, mac_sha,kea_rsa_export_1024}, + cipher_des, mac_sha,kea_rsa_export_1024, ssl_hash_none}, {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, - cipher_rc4_56, mac_sha,kea_rsa_export_1024}, + cipher_rc4_56, mac_sha,kea_rsa_export_1024, ssl_hash_none}, - {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips}, - {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips}, + {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips, ssl_hash_none}, + {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips, ssl_hash_none}, + + {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa, ssl_hash_sha256}, + {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa, ssl_hash_sha256}, - {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa}, - {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa}, #ifndef NSS_DISABLE_ECC - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa}, + {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa, ssl_hash_sha256}, + {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256}, + {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha384}, + {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_ecdhe_rsa, ssl_hash_sha384}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, hmac_sha384, kea_ecdhe_ecdsa, ssl_hash_sha384}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, hmac_sha384, kea_ecdhe_rsa, ssl_hash_sha384}, #endif /* NSS_DISABLE_ECC */ - {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss}, - {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss}, - {TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_dss}, + {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss, ssl_hash_sha256}, + {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss, ssl_hash_sha256}, + {TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_dss, ssl_hash_sha256}, + {TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_dhe_dss, ssl_hash_sha384}, + {TLS_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_rsa, ssl_hash_sha384}, - {TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_dhe_rsa}, + {TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_dhe_rsa, ssl_hash_sha256}, #ifndef NSS_DISABLE_ECC - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_rsa}, - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa}, - - {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa}, - {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa}, - {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa}, - {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa}, - {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa}, - - {TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_ecdsa}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_ecdsa}, - {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_ecdsa}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa}, - - {TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_rsa}, - {TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_rsa}, - {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_rsa}, - {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_rsa}, - {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_rsa}, - - {TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_rsa}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_rsa}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_rsa}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_rsa}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_rsa, ssl_hash_sha256}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256}, + + {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, + {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, + {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, + {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, + {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, + + {TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, + {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, + {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_ecdsa, ssl_hash_sha256}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, + + {TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_rsa, ssl_hash_none}, + {TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_rsa, ssl_hash_none}, + {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_rsa, ssl_hash_none}, + {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_rsa, ssl_hash_none}, + {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_rsa, ssl_hash_none}, + + {TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_rsa, ssl_hash_sha256}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, #if 0 - {TLS_ECDH_anon_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_anon}, - {TLS_ECDH_anon_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_anon}, - {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_anon}, - {TLS_ECDH_anon_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_anon}, - {TLS_ECDH_anon_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_anon, ssl_hash_none}, + {TLS_ECDH_anon_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_anon, ssl_hash_none}, + {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_anon, ssl_hash_none}, + {TLS_ECDH_anon_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_anon, ssl_hash_none}, + {TLS_ECDH_anon_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_anon, ssl_hash_none}, #endif - {TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_psk}, + {TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_psk, ssl_hash_sha256}, #endif /* NSS_DISABLE_ECC */ }; /* clang-format on */ @@ -534,6 +552,7 @@ static const SSLCipher2Mech alg2Mech[] = { #define mmech_md5_hmac CKM_MD5_HMAC #define mmech_sha_hmac CKM_SHA_1_HMAC #define mmech_sha256_hmac CKM_SHA256_HMAC +#define mmech_sha384_hmac CKM_SHA384_HMAC /* clang-format off */ static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */ @@ -546,6 +565,7 @@ static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */ {hmac_sha, mmech_sha_hmac, 0, SHA1_LENGTH, SEC_OID_HMAC_SHA1}, {hmac_sha256, mmech_sha256_hmac, 0, SHA256_LENGTH, SEC_OID_HMAC_SHA256}, { mac_aead, mmech_invalid, 0, 0, 0 }, + {hmac_sha384, mmech_sha384_hmac, 0, SHA384_LENGTH, SEC_OID_HMAC_SHA384} }; /* clang-format on */ @@ -742,20 +762,27 @@ ssl3_CipherSuiteAllowedForVersionRange( case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case TLS_RSA_WITH_AES_256_CBC_SHA256: case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case TLS_RSA_WITH_AES_128_CBC_SHA256: case TLS_RSA_WITH_AES_128_GCM_SHA256: + case TLS_RSA_WITH_AES_256_GCM_SHA384: case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: case TLS_RSA_WITH_NULL_SHA256: case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2; case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2; @@ -2556,6 +2583,9 @@ ssl3_ComputeRecordMAC( case ssl_hmac_sha256: /* used with TLS */ hashObj = HASH_GetRawHashObject(HASH_AlgSHA256); break; + case ssl_hmac_sha384: /* used with TLS */ + hashObj = HASH_GetRawHashObject(HASH_AlgSHA384); + break; default: break; } @@ -3872,6 +3902,31 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) return SECSuccess; } +inline static CK_MECHANISM_TYPE +ssl3_GetTls12PrfHashMechanism(sslSocket *ss) +{ + switch (ss->ssl3.hs.suite_def->prf_hash) { + case ssl_hash_sha384: + return CKM_SHA384; + case ssl_hash_sha256: + case ssl_hash_none: + /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */ + return CKM_SHA256; + default: + PORT_Assert(0); + } + return CKM_SHA256; +} + +inline static SSLHashType +ssl3_GetSuitePrfHash(sslSocket *ss) { + /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */ + if (ss->ssl3.hs.suite_def->prf_hash == ssl_hash_none) { + return ssl_hash_sha256; + } + return ss->ssl3.hs.suite_def->prf_hash; +} + /* This method completes the derivation of the MS from the PMS. ** ** 1. Derive the MS, if possible, else return an error. @@ -3995,7 +4050,7 @@ ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms, master_params.RandomInfo.pServerRandom = sr; master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; if (isTLS12) { - master_params.prfHashMechanism = CKM_SHA256; + master_params.prfHashMechanism = ssl3_GetTls12PrfHashMechanism(ss); master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS); } else { /* prfHashMechanism is not relevant with this PRF */ @@ -4238,7 +4293,7 @@ ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss) if (isTLS12) { key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE; - key_material_params.prfHashMechanism = CKM_SHA256; + key_material_params.prfHashMechanism = ssl3_GetTls12PrfHashMechanism(ss); key_material_params_len = sizeof(CK_TLS12_KEY_MAT_PARAMS); } else if (isTLS) { key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; @@ -4303,7 +4358,8 @@ loser: } /* ssl3_InitHandshakeHashes creates handshake hash contexts and hashes in - * buffered messages in ss->ssl3.hs.messages. */ + * buffered messages in ss->ssl3.hs.messages. Called from + * ssl3_NegotiateCipherSuite() and ssl3_HandleServerHello. */ static SECStatus ssl3_InitHandshakeHashes(sslSocket *ss) { @@ -4314,9 +4370,18 @@ ssl3_InitHandshakeHashes(sslSocket *ss) if (ss->opt.bypassPKCS11) { PORT_Assert(!ss->ssl3.hs.sha_obj && !ss->ssl3.hs.sha_clone); if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) { - /* If we ever support ciphersuites where the PRF hash isn't SHA-256 - * then this will need to be updated. */ - ss->ssl3.hs.sha_obj = HASH_GetRawHashObject(HASH_AlgSHA256); + const SECOidData *hashOid = + SECOID_FindOIDByMechanism(ssl3_GetTls12PrfHashMechanism(ss)); + + if (hashOid == NULL) { + PORT_Assert(hashOid == NULL); + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); + return SECFailure; + } + + ss->ssl3.hs.sha_obj = HASH_GetRawHashObject( + HASH_GetHashTypeByOidTag(hashOid->offset)); + if (!ss->ssl3.hs.sha_obj) { ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); return SECFailure; @@ -4339,9 +4404,20 @@ ssl3_InitHandshakeHashes(sslSocket *ss) * that the master secret will wind up in ... */ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) { - /* If we ever support ciphersuites where the PRF hash isn't SHA-256 - * then this will need to be updated. */ - ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA256); + /* determine the hash from the prf */ + const SECOidData *hash_oid = + SECOID_FindOIDByMechanism(ssl3_GetTls12PrfHashMechanism(ss)); + + /* Get the PKCS #11 mechanism for the Hash from the cipher suite (prf_hash) + * Convert that to the OidTag. We can then use that OidTag to create our + * PK11Context */ + PORT_Assert(hash_oid != NULL); + if (hash_oid == NULL) { + ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); + return SECFailure; + } + + ss->ssl3.hs.sha = PK11_CreateDigestContext(hash_oid->offset); if (ss->ssl3.hs.sha == NULL) { ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); return SECFailure; @@ -4661,6 +4737,12 @@ ssl3_AppendSignatureAndHashAlgorithm( sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash) { PRUint8 serialized[2]; + SECOidTag hashAlg = ssl3_TLSHashAlgorithmToOID(sigAndHash->hashAlg); + if (hashAlg == SEC_OID_UNKNOWN) { + PORT_Assert(hashAlg != SEC_OID_UNKNOWN); + PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); + return SECFailure; + } serialized[0] = (PRUint8)sigAndHash->hashAlg; serialized[1] = (PRUint8)sigAndHash->sigAlg; @@ -4776,7 +4858,10 @@ ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes, } /* tlsHashOIDMap contains the mapping between TLS hash identifiers and the - * SECOidTag used internally by NSS. */ + * SECOidTag used internally by NSS. + * + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + */ static const struct { SSLHashType tlsHash; SECOidTag oid; @@ -4999,11 +5084,11 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len, sizeof(hashes->u.raw)); - PRINT_BUF(60, (NULL, "SHA-256: result", hashes->u.raw, hashes->len)); + PRINT_BUF(60, (NULL, "HASH: result", hashes->u.raw, hashes->len)); /* If we ever support ciphersuites where the PRF hash isn't SHA-256 * then this will need to be updated. */ - hashes->hashAlg = ssl_hash_sha256; + hashes->hashAlg = ssl3_GetSuitePrfHash(ss); rv = SECSuccess; } else if (ss->opt.bypassPKCS11) { /* compute them without PKCS11 */ @@ -5111,9 +5196,8 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, rv = SECFailure; goto tls12_loser; } - /* If we ever support ciphersuites where the PRF hash isn't SHA-256 - * then this will need to be updated. */ - hashes->hashAlg = ssl_hash_sha256; + + hashes->hashAlg = ssl3_GetSuitePrfHash(ss); rv = SECSuccess; tls12_loser: @@ -6769,6 +6853,20 @@ done: return rv; } +/* Once a cipher suite has been selected, make sure that the necessary secondary + * information is properly set. */ +static SECStatus +ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite) +{ + ss->ssl3.hs.cipher_suite = chosenSuite; + ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(chosenSuite); + ss->ssl3.hs.kea_def = &kea_defs[ss->ssl3.hs.suite_def->key_exchange_alg]; + ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; + + /* Now we've have a cipher suite, initialize the handshake hashes. */ + return ssl3_InitHandshakeHashes(ss); +} + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete * ssl3 ServerHello message. * Caller must hold Handshake and RecvBuf locks. @@ -6846,13 +6944,6 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); - rv = ssl3_InitHandshakeHashes(ss); - if (rv != SECSuccess) { - desc = internal_error; - errCode = PORT_GetError(); - goto alert_loser; - } - rv = ssl3_ConsumeHandshake( ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length); if (rv != SECSuccess) { @@ -6929,17 +7020,13 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) errCode = SSL_ERROR_NO_CYPHER_OVERLAP; goto alert_loser; } - ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp; - ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp); - ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; - PORT_Assert(ss->ssl3.hs.suite_def); - if (!ss->ssl3.hs.suite_def) { - errCode = SEC_ERROR_LIBRARY_FAILURE; - PORT_SetError(errCode); - goto loser; /* we don't send alerts for our screw-ups. */ - } - ss->ssl3.hs.kea_def = &kea_defs[ss->ssl3.hs.suite_def->key_exchange_alg]; + rv = ssl3_SetCipherSuite(ss, (ssl3CipherSuite)temp); + if (rv != SECSuccess) { + desc = internal_error; + errCode = PORT_GetError(); + goto alert_loser; + } if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { /* find selected compression method in our list. */ @@ -7575,7 +7662,7 @@ done: /* Destroys the backup handshake hash context if we don't need it. Note that * this function selects the hash algorithm for client authentication * signatures; ssl3_SendCertificateVerify uses the presence of the backup hash - * to determine whether to use SHA-1 or SHA-256. */ + * to determine whether to use SHA-1, or the PRF hash of the cipher suite. */ static void ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, const SECItem *algorithms) @@ -7584,7 +7671,7 @@ ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, SSLSignType sigAlg; PRBool preferSha1 = PR_FALSE; PRBool supportsSha1 = PR_FALSE; - PRBool supportsSha256 = PR_FALSE; + PRBool supportsHandshakeHash = PR_FALSE; PRBool needBackupHash = PR_FALSE; unsigned int i; @@ -7608,15 +7695,15 @@ ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, if (algorithms->data[i + 1] == sigAlg) { if (algorithms->data[i] == ssl_hash_sha1) { supportsSha1 = PR_TRUE; - } else if (algorithms->data[i] == ssl_hash_sha256) { - supportsSha256 = PR_TRUE; + } else if (algorithms->data[i] == ss->ssl3.hs.suite_def->prf_hash) { + supportsHandshakeHash = PR_TRUE; } } } - /* If either the server does not support SHA-256 or the client key prefers + /* If either the server does not support the handshake hash or the client key prefers * SHA-1, leave the backup hash. */ - if (supportsSha1 && (preferSha1 || !supportsSha256)) { + if (supportsSha1 && (preferSha1 || !supportsHandshakeHash)) { needBackupHash = PR_TRUE; } @@ -8365,7 +8452,6 @@ ssl3_KEASupportsTickets(const ssl3KEADef *kea_def) SECStatus ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites) { - ssl3CipherSuiteCfg *chosenSuite = NULL; int j; int i; @@ -8378,14 +8464,7 @@ ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites) for (i = 0; i + 1 < suites->len; i += 2) { PRUint16 suite_i = (suites->data[i] << 8) | suites->data[i + 1]; if (suite_i == suite->cipher_suite) { - chosenSuite = suite; - ss->ssl3.hs.cipher_suite = chosenSuite->cipher_suite; - ss->ssl3.hs.suite_def = - ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); - ss->ssl3.hs.kea_def = - &kea_defs[ss->ssl3.hs.suite_def->key_exchange_alg]; - ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; - return SECSuccess; + return ssl3_SetCipherSuite(ss, suite_i); } } } @@ -8680,13 +8759,6 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3; ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; - rv = ssl3_InitHandshakeHashes(ss); - if (rv != SECSuccess) { - desc = internal_error; - errCode = PORT_GetError(); - goto alert_loser; - } - /* Generate the Server Random now so it is available * when we process the ClientKeyShare in TLS 1.3 */ rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random); @@ -9040,17 +9112,17 @@ ssl3_HandleClientHelloPart2(sslSocket *ss, if (!suite->enabled) break; #endif - /* Double check that the cached cipher suite is in the client's list */ + /* Double check that the cached cipher suite is in the client's + * list. If it isn't, fall through and start a new session. */ for (i = 0; i + 1 < suites->len; i += 2) { PRUint16 suite_i = (suites->data[i] << 8) | suites->data[i + 1]; if (suite_i == suite->cipher_suite) { - ss->ssl3.hs.cipher_suite = - suite->cipher_suite; - ss->ssl3.hs.suite_def = - ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); - ss->ssl3.hs.kea_def = - &kea_defs[ss->ssl3.hs.suite_def->key_exchange_alg]; - ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; + rv = ssl3_SetCipherSuite(ss, suite_i); + if (rv != SECSuccess) { + desc = internal_error; + errCode = PORT_GetError(); + goto alert_loser; + } /* Use the cached compression method. */ ss->ssl3.hs.compression = @@ -9470,13 +9542,6 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, } ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; - rv = ssl3_InitHandshakeHashes(ss); - if (rv != SECSuccess) { - desc = internal_error; - errCode = PORT_GetError(); - goto alert_loser; - } - /* if we get a non-zero SID, just ignore it. */ if (length != total) { SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d", @@ -9531,12 +9596,12 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, for (i = 0; i + 2 < suite_length; i += 3) { PRUint32 suite_i = (suites[i] << 16) | (suites[i + 1] << 8) | suites[i + 2]; if (suite_i == suite->cipher_suite) { - ss->ssl3.hs.cipher_suite = suite->cipher_suite; - ss->ssl3.hs.suite_def = - ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); - ss->ssl3.hs.kea_def = - &kea_defs[ss->ssl3.hs.suite_def->key_exchange_alg]; - ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite; + rv = ssl3_SetCipherSuite(ss, suite_i); + if (rv != SECSuccess) { + desc = internal_error; + errCode = PORT_GetError(); + goto alert_loser; + } goto suite_found; } } @@ -9550,7 +9615,7 @@ suite_found: * TLS_FALLBACK_SCSV and reject the connection if found. */ if (ss->vrange.max > ss->clientHelloVersion) { for (i = 0; i + 2 < suite_length; i += 3) { - PRUint16 suite_i = (suites[i + 1] << 8) | suites[i + 2]; + PRUint16 suite_i = (suites[i] << 16) | (suites[i + 1] << 8) | suites[i + 2]; if (suite_i == TLS_FALLBACK_SCSV) { desc = inappropriate_fallback; errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT; @@ -10070,6 +10135,8 @@ ssl3_EncodeCertificateRequestSigAlgs(sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 *len) { unsigned int i; + /* We only track a single hash, the one that is the basis for the PRF. */ + SSLHashType suiteHashAlg = ssl3_GetSuitePrfHash(ss); PORT_Assert(maxLen >= ss->ssl3.signatureAlgorithmCount * 2); if (maxLen < ss->ssl3.signatureAlgorithmCount * 2) { @@ -10081,9 +10148,9 @@ ssl3_EncodeCertificateRequestSigAlgs(sslSocket *ss, PRUint8 *buf, for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) { const SSLSignatureAndHashAlg *alg = &ss->ssl3.signatureAlgorithms[i]; /* Note that we don't support a handshake hash with anything other than - * SHA-256, so asking for a signature from clients for something else - * would be inviting disaster. */ - if (alg->hashAlg == ssl_hash_sha256) { + * the PRF hash, so asking for a signature from clients for something + * else would be inviting disaster. */ + if (alg->hashAlg == suiteHashAlg) { buf[(*len)++] = (PRUint8)alg->hashAlg; buf[(*len)++] = (PRUint8)alg->sigAlg; } @@ -11597,7 +11664,7 @@ done: } static SECStatus -ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, +ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec, PRBool isServer, const SSL3Hashes *hashes, TLSFinished *tlsFinished) @@ -11620,7 +11687,7 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, if (spec->version < SSL_LIBRARY_VERSION_TLS_1_2) { tls_mac_params.prfMechanism = CKM_TLS_PRF; } else { - tls_mac_params.prfMechanism = CKM_SHA256; + tls_mac_params.prfMechanism = ssl3_GetTls12PrfHashMechanism(ss); } tls_mac_params.ulMacLength = 12; tls_mac_params.ulServerOrClient = isServer ? 1 : 2; @@ -11825,7 +11892,7 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags) isTLS = (PRBool)(cwSpec->version > SSL_LIBRARY_VERSION_3_0); rv = ssl3_ComputeHandshakeHashes(ss, cwSpec, &hashes, sender); if (isTLS && rv == SECSuccess) { - rv = ssl3_ComputeTLSFinished(cwSpec, isServer, &hashes, &tlsFinished); + rv = ssl3_ComputeTLSFinished(ss, cwSpec, isServer, &hashes, &tlsFinished); } ssl_ReleaseSpecReadLock(ss); if (rv != SECSuccess) { @@ -11996,7 +12063,7 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED); return SECFailure; } - rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer, + rv = ssl3_ComputeTLSFinished(ss, ss->ssl3.crSpec, !isServer, hashes, &tlsFinished); if (!isServer) ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished; diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c index b1693125f..ad08f4171 100644 --- a/lib/ssl/ssl3ecc.c +++ b/lib/ssl/ssl3ecc.c @@ -1049,7 +1049,9 @@ static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_NULL_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, @@ -1061,7 +1063,9 @@ static const ssl3CipherSuite ecdhe_rsa_suites[] = { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_NULL_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, @@ -1078,11 +1082,15 @@ static const ssl3CipherSuite ecSuites[] = { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_NULL_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_NULL_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, diff --git a/lib/ssl/sslenum.c b/lib/ssl/sslenum.c index ae1fd7d05..ffa85c04b 100644 --- a/lib/ssl/sslenum.c +++ b/lib/ssl/sslenum.c @@ -22,7 +22,11 @@ * * No-encryption cipher suites last * * Export/weak/obsolete cipher suites before no-encryption cipher suites * * Order by key exchange algorithm: ECDHE, then DHE, then ECDH, RSA. - * * Within key agreement sections, order by symmetric encryption algorithm: + * * Within key agreement sections, prefer AEAD over non-AEAD cipher suites. + * * Within AEAD sections, order by symmetric encryption algorithm which + * integrates message authentication algorithm: AES-128-GCM, then + * ChaCha20-Poly1305, then AES-256-GCM, + * * Within non-AEAD sections, order by symmetric encryption algorithm: * AES-128, then Camellia-128, then AES-256, then Camellia-256, then SEED, * then FIPS-3DES, then 3DES, then RC4. AES is commonly accepted as a * strong cipher internationally, and is often hardware-accelerated. @@ -30,6 +34,9 @@ * organizations. SEED is only recommended by the Korean government. 3DES * only provides 112 bits of security. RC4 is now deprecated or forbidden * by many standards organizations. + * * Within non-AEAD symmetric algorithm sections, order by message + * authentication algorithm: HMAC-SHA256, then HMAC-SHA384, then HMAC-SHA1, + * then HMAC-MD5. * * Within symmetric algorithm sections, order by message authentication * algorithm: GCM, then HMAC-SHA1, then HMAC-SHA256, then HMAC-MD5. * * Within message authentication algorithm sections, order by asymmetric @@ -57,6 +64,8 @@ const PRUint16 SSL_ImplementedCiphers[] = { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA must appear before * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA to work around bug 946147. */ @@ -66,6 +75,8 @@ const PRUint16 SSL_ImplementedCiphers[] = { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, @@ -75,6 +86,8 @@ const PRUint16 SSL_ImplementedCiphers[] = { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, @@ -103,6 +116,7 @@ const PRUint16 SSL_ImplementedCiphers[] = { #endif /* NSS_DISABLE_ECC */ TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h index 0602fb2ce..19a97845b 100644 --- a/lib/ssl/sslimpl.h +++ b/lib/ssl/sslimpl.h @@ -57,6 +57,7 @@ typedef SSLMACAlgorithm SSL3MACAlgorithm; #define hmac_md5 ssl_hmac_md5 #define hmac_sha ssl_hmac_sha #define hmac_sha256 ssl_hmac_sha256 +#define hmac_sha384 ssl_hmac_sha384 #define mac_aead ssl_mac_aead #define SET_ERROR_CODE /* reminder */ @@ -314,9 +315,9 @@ typedef struct { } ssl3CipherSuiteCfg; #ifndef NSS_DISABLE_ECC -#define ssl_V3_SUITES_IMPLEMENTED 68 +#define ssl_V3_SUITES_IMPLEMENTED 75 #else -#define ssl_V3_SUITES_IMPLEMENTED 39 +#define ssl_V3_SUITES_IMPLEMENTED 42 #endif /* NSS_DISABLE_ECC */ #define MAX_DTLS_SRTP_CIPHER_SUITES 4 @@ -468,6 +469,7 @@ typedef enum { cipher_camellia_256, cipher_seed, cipher_aes_128_gcm, + cipher_aes_256_gcm, cipher_chacha20, cipher_missing /* reserved for no such supported cipher */ /* This enum must match ssl3_cipherName[] in ssl3con.c. */ @@ -718,6 +720,7 @@ typedef struct ssl3CipherSuiteDefStr { SSL3BulkCipher bulk_cipher_alg; SSL3MACAlgorithm mac_alg; SSL3KeyExchangeAlgorithm key_exchange_alg; + SSLHashType prf_hash; } ssl3CipherSuiteDef; /* diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c index 73ff86c1b..54959de1f 100644 --- a/lib/ssl/sslinfo.c +++ b/lib/ssl/sslinfo.c @@ -189,6 +189,7 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, /* "mac algorithm" and size */ #define M_AEAD_128 "AEAD", ssl_mac_aead, 128 +#define M_SHA384 "SHA384", ssl_hmac_sha384, 384 #define M_SHA256 "SHA256", ssl_hmac_sha256, 256 #define M_SHA "SHA1", ssl_mac_sha, 160 #define M_MD5 "MD5", ssl_mac_md5, 128 @@ -283,7 +284,15 @@ static const SSLCipherSuiteInfo suiteInfo[] = { { 0, CS(ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_RSAS }, { 0, CS(ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_RSAS }, { 0, CS(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_RSAS }, + { 0, CS(ECDHE_RSA_WITH_AES_256_CBC_SHA384), S_RSA, K_ECDHE, C_AES, B_256, M_SHA384, F_FIPS_STD, A_RSAS }, + { 0, CS(ECDHE_ECDSA_WITH_AES_256_CBC_SHA384), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA384, F_FIPS_STD, A_ECDSA }, + { 0, CS(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384), S_ECDSA, K_ECDHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_ECDSA }, + { 0, CS(ECDHE_RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_ECDHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAS }, #endif /* NSS_DISABLE_ECC */ + + { 0, CS(DHE_DSS_WITH_AES_256_GCM_SHA384), S_DSA, K_DHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_DSA }, + { 0, CS(DHE_RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_DHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAS }, + { 0, CS(RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_RSA, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAD } }; #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0])) diff --git a/lib/ssl/sslproto.h b/lib/ssl/sslproto.h index 4c668fcab..1e7208c73 100644 --- a/lib/ssl/sslproto.h +++ b/lib/ssl/sslproto.h @@ -164,8 +164,11 @@ #define TLS_RSA_WITH_SEED_CBC_SHA 0x0096 #define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C +#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D #define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E +#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F #define TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 0x00A2 +#define TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 0x00A3 /* TLS "Signaling Cipher Suite Value" (SCSV). May be requested by client. * Must NEVER be chosen by server. SSL 3.0 server acknowledges by sending @@ -212,11 +215,15 @@ #define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 +#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 #define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B +#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C #define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F +#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 #define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h index cad9087fe..759e04ff4 100644 --- a/lib/ssl/sslt.h +++ b/lib/ssl/sslt.h @@ -130,7 +130,8 @@ typedef enum { ssl_hmac_md5 = 3, /* TLS HMAC version of mac_md5 */ ssl_hmac_sha = 4, /* TLS HMAC version of mac_sha */ ssl_hmac_sha256 = 5, - ssl_mac_aead = 6 + ssl_mac_aead = 6, + ssl_hmac_sha384 = 7 } SSLMACAlgorithm; typedef enum { diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c index 4272c19f8..22c89a6f3 100644 --- a/lib/ssl/tls13con.c +++ b/lib/ssl/tls13con.c @@ -237,21 +237,52 @@ tls13_CheckHsState(sslSocket *ss, int err, const char *error_name, SSLHashType tls13_GetHash(sslSocket *ss) { - /* TODO(ekr@rtfm.com): This needs to actually be looked up. */ + /* All TLS 1.3 cipher suites must have an explict PRF hash. */ + PORT_Assert(ss->ssl3.hs.suite_def->prf_hash != ssl_hash_none); + return ss->ssl3.hs.suite_def->prf_hash; +} + +unsigned int +tls13_GetHashSize(sslSocket *ss) +{ + switch (tls13_GetHash(ss)) { + case ssl_hash_sha256: + return 32; + case ssl_hash_sha384: + return 48; + default: + PORT_Assert(0); + return ssl_hash_sha256; + } return ssl_hash_sha256; } CK_MECHANISM_TYPE tls13_GetHkdfMechanism(sslSocket *ss) { - /* TODO(ekr@rtfm.com): This needs to actually be looked up. */ + switch (tls13_GetHash(ss)) { + case ssl_hash_sha256: + return CKM_NSS_HKDF_SHA256; + case ssl_hash_sha384: + return CKM_NSS_HKDF_SHA384; + default: + /*PORT_Assert(0);*/ + return CKM_NSS_HKDF_SHA256; + } return CKM_NSS_HKDF_SHA256; } static CK_MECHANISM_TYPE tls13_GetHmacMechanism(sslSocket *ss) { - /* TODO(ekr@rtfm.com): This needs to actually be looked up. */ + switch (tls13_GetHash(ss)) { + case ssl_hash_sha256: + return CKM_SHA256_HMAC; + case ssl_hash_sha384: + return CKM_SHA384_HMAC; + default: + PORT_Assert(0); + } return CKM_SHA256_HMAC; } @@ -350,7 +381,9 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid) PK11SymKey *wrapKey; /* wrapping key */ PK11SymKey *SS = NULL; SECItem wrappedMS = { siBuffer, NULL, 0 }; + SSLHashType hashType; SECStatus rv; + SSL_TRC(3, ("%d: TLS13[%d]: recovering static secret (%s)", SSL_GETPID(), ss->fd, ss->sec.isServer ? "server" : "client")); @@ -390,11 +423,12 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid) wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; /* unwrap the "master secret" which becomes SS. */ - PORT_Assert(tls13_GetHash(ss) == ssl_hash_sha256); + hashType = tls13_GetHash(ss); + PORT_Assert(hashType == ssl_hash_sha256 || hashType == ssl_hash_sha384); SS = PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE, - CKA_DERIVE, 32, + CKA_DERIVE, hashType, CKF_SIGN | CKF_VERIFY); PK11_FreeSymKey(wrapKey); if (!SS) { @@ -451,9 +485,12 @@ tls13_AllowPskCipher(const sslSocket *ss, const ssl3CipherSuiteDef *cipher_def) if (cached_cipher_def->bulk_cipher_alg != cipher_def->bulk_cipher_alg) return PR_FALSE; + + /* PSK cipher must have the same PSK hash as was negotiated before. */ + if (cipher_def->prf_hash != cached_cipher_def->prf_hash) { + return PR_FALSE; + } } - /* TODO(ekr@rtfm.com): Check the KDF code whenever we have - * adjustable KDFs. */ SSL_TRC(3, ("%d: TLS 1.3[%d]: Enabling cipher suite suite 0x%04x", SSL_GETPID(), ss->fd, cipher_def->cipher_suite)); @@ -1336,13 +1373,8 @@ tls13_AddContextToHashes(sslSocket *ss, SSL3Hashes *hashes /* IN/OUT */, : server_cert_verify_string; unsigned int hashlength; - /* Double check that we are doing SHA-256 for the handshake hash.*/ - PORT_Assert(hashes->hashAlg == ssl_hash_sha256); - if (hashes->hashAlg != ssl_hash_sha256) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto loser; - } - PORT_Assert(hashes->len == 32); + /* Double check that we are doing the same hash.*/ + PORT_Assert(hashes->len == tls13_GetHashSize(ss)); ctx = PK11_CreateDigestContext(ssl3_TLSHashAlgorithmToOID(algorithm)); if (!ctx) { @@ -1597,14 +1629,11 @@ tls13_ComputeHandshakeHashes(sslSocket *ss, PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); /* TODO(ekr@rtfm.com): This first clause is futureproofing for * 0-RTT. */ - if (ss->ssl3.hs.hashType == handshake_hash_unknown) { - PORT_Assert(0); - } else { - ctx = PK11_CloneContext(ss->ssl3.hs.sha); - if (!ctx) { - ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); - return SECFailure; - } + PORT_Assert(ss->ssl3.hs.hashType != handshake_hash_unknown); + ctx = PK11_CloneContext(ss->ssl3.hs.sha); + if (!ctx) { + ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); + return SECFailure; } rv = PK11_DigestFinal(ctx, hashes->u.raw, &hashes->len, @@ -1619,8 +1648,8 @@ tls13_ComputeHandshakeHashes(sslSocket *ss, /* If we ever support ciphersuites where the PRF hash isn't SHA-256 * then this will need to be updated. */ - PORT_Assert(hashes->len == 32); - hashes->hashAlg = ssl_hash_sha256; + PORT_Assert(hashes->len == tls13_GetHashSize(ss)); + hashes->hashAlg = tls13_GetHash(ss); PK11_DestroyContext(ctx, PR_TRUE); return SECSuccess; diff --git a/lib/ssl/tls13hkdf.c b/lib/ssl/tls13hkdf.c index c3fec2953..2b131ef53 100644 --- a/lib/ssl/tls13hkdf.c +++ b/lib/ssl/tls13hkdf.c @@ -97,7 +97,10 @@ tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash, { CK_NSS_HKDFParams params; SECItem paramsi = { siBuffer, NULL, 0 }; - PRUint8 info[100]; + /* Size of info array needs to be big enough to hold the maximum Prefix, + * Label, plus HandshakeHash. If it's ever to small, the code will abort. + */ + PRUint8 info[110]; PRUint8 *ptr = info; unsigned int infoLen; PK11SymKey *derived; diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh index 4143b67ef..896f64710 100755 --- a/tests/ssl/ssl.sh +++ b/tests/ssl/ssl.sh @@ -83,14 +83,21 @@ ssl_init() USER_NICKNAME=TestUser NORM_EXT="" + EC_SUITES=":C001:C002:C003:C004:C005:C006:C007:C008:C009:C00A:C00B:C00C:C00D" + EC_SUITES="${EC_SUITES}:C00E:C00F:C010:C011:C012:C013:C014:C023:C024:C027" + EC_SUITES="${EC_SUITES}:C028:C02B:C02C:C02F:C030:CCA8:CCA9:CCAA" + + NON_EC_SUITES=":0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B" + NON_EC_SUITES="${NON_EC_SUITES}:0084:009C:009D:009E:009F:00A2:00A3:CCAAcdefgijklmnvyz" + if [ -z "$NSS_DISABLE_ECC" ] ; then ECC_STRING=" - with ECC" # List of cipher suites to test, including ECC cipher suites. - CIPHER_SUITES="-c :C001:C002:C003:C004:C005:C006:C007:C008:C009:C00A:C00B:C00C:C00D:C00E:C00F:C010:C011:C012:C013:C014:C023:C027:C02B:C02F:CCA8:CCA9:CCAA:0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B:0084:009C:009E:00A2cdefgijklmnvyz" + CIPHER_SUITES="-c ${EC_SUITES}${NON_EC_SUITES}" else ECC_STRING="" # List of cipher suites to test, excluding ECC cipher suites. - CIPHER_SUITES="-c :0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B:0084:009C:009E:00A2:CCAAcdefgijklmnvyz" + CIPHER_SUITES="-c ${NON_EC_SUITES}" fi if [ "${OS_ARCH}" != "WINNT" ]; then diff --git a/tests/ssl/sslcov.txt b/tests/ssl/sslcov.txt index 4dbe207be..8d0aa89f5 100644 --- a/tests/ssl/sslcov.txt +++ b/tests/ssl/sslcov.txt @@ -21,6 +21,9 @@ noECC SSL3 v SSL3_RSA_WITH_AES_128_CBC_SHA noECC SSL3 y SSL3_RSA_WITH_AES_256_CBC_SHA noECC SSL3 z SSL3_RSA_WITH_NULL_SHA + noECC TLS12 :009F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + noECC TLS12 :00A3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 + noECC TLS12 :009D TLS_RSA_WITH_AES_256_GCM_SHA384 # noECC SSL3 :0041 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA # noECC SSL3 :0084 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA # @@ -154,8 +157,12 @@ ECC TLS12 :C013 TLS12_ECDHE_RSA_WITH_AES_128_CBC_SHA ECC TLS12 :C014 TLS12_ECDHE_RSA_WITH_AES_256_CBC_SHA ECC TLS12 :C023 TLS12_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + ECC TLS12 :C024 TLS12_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ECC TLS12 :C027 TLS12_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + ECC TLS12 :C028 TLS12_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ECC TLS12 :C02B TLS12_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + ECC TLS12 :C02C TLS12_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ECC TLS12 :C02F TLS12_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + ECC TLS12 :C030 TLS12_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ECC TLS12 :CCA8 TLS12_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 ECC TLS12 :CCA9 TLS12_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 |