Add support for TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 This TLS 1.2 cipher is substantially inferior to AES-GCM and should never be used; it was previously removed in 2018. We add it back for backwards-compatibility with devices that cannot be updated. It is added as a deprecated cipher and is not available unless configured explicitly by name. Change-Id: Idc85ab4f1eb38768edba6562345d77616a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/86687 Reviewed-by: David Benjamin <davidben@google.com> Auto-Submit: Lily Chen <chlily@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 0e99279..bc66010 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h
@@ -1472,6 +1472,7 @@ #define SSL_CIPHER_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xc014 #define SSL_CIPHER_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xc035 #define SSL_CIPHER_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xc036 +#define SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xc023 #define SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xc027 #define SSL_CIPHER_RSA_WITH_AES_128_GCM_SHA256 0x009c #define SSL_CIPHER_RSA_WITH_AES_256_GCM_SHA384 0x009d
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index ea55e2a..696ccfd 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h
@@ -187,6 +187,7 @@ #define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A #define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 #define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0x0300C023 #define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0x0300C027 #define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B #define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C @@ -220,6 +221,7 @@ #define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" #define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" #define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 "ECDHE-ECDSA-AES128-SHA256" #define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA256 "ECDHE-RSA-AES128-SHA256" #define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \ "ECDHE-ECDSA-AES128-GCM-SHA256"
diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc index 108681c..1cda428 100644 --- a/ssl/ssl_cipher.cc +++ b/ssl/ssl_cipher.cc
@@ -213,7 +213,21 @@ SSL_HANDSHAKE_MAC_DEFAULT, }, - // Cipher C027 + // HMAC based TLS v1.2 ciphersuites from RFC5289 + + // Cipher C023 (deprecated) + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C027 (deprecated) { TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", @@ -642,7 +656,9 @@ } bool ssl_cipher_is_deprecated(const SSL_CIPHER *cipher) { - return cipher->protocol_id == SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256 || + return cipher->protocol_id == + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 || + cipher->protocol_id == SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256 || cipher->algorithm_enc == SSL_3DES; } @@ -1007,8 +1023,7 @@ } // We prefer ECDHE ciphers over non-PFS ciphers. Then we prefer AEAD over - // non-AEAD. The constants are masked by 0xffff to remove the vestigial 0x03 - // byte from SSL 2.0. + // non-AEAD. static const uint16_t kAESCiphers[] = { SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_CIPHER_ECDHE_RSA_WITH_AES_128_GCM_SHA256, @@ -1027,6 +1042,7 @@ SSL_CIPHER_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_CIPHER_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_CIPHER_ECDHE_PSK_WITH_AES_256_CBC_SHA, + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_CIPHER_RSA_WITH_AES_128_GCM_SHA256, SSL_CIPHER_RSA_WITH_AES_256_GCM_SHA384,
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index 05f95e0..9b75ef0 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc
@@ -480,9 +480,17 @@ "SHA1", "RSA", "SSLv3", "TLSv1", "TLSv1.2", }; -static const char *kShouldIncludeCBCSHA256[] = { - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", +static const struct { + const char *rule; + int expected_included_deprecated_count; +} kDeprecatedCBCSHA256Rules[] = { + {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 1}, + {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 1}, + {"ALL:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 1}, + {"ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 1}, + {"ALL:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:TLS_ECDHE_RSA_WITH_AES_128_" + "CBC_SHA256", + 2}, }; static const CurveTest kCurveTests[] = { @@ -624,23 +632,22 @@ EXPECT_FALSE(ssl_cipher_is_deprecated(cipher)); } } +} - { - for (const char *rule : kShouldIncludeCBCSHA256) { - bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method())); - ASSERT_TRUE(ctx); - ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule)); +TEST(SSLTest, CipherRulesDeprecated) { + for (const auto& test : kDeprecatedCBCSHA256Rules) { + SCOPED_TRACE(test.rule); + bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); + ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), test.rule)); - bool found = false; - for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) { - if (SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256 == - SSL_CIPHER_get_protocol_id(cipher)) { - found = true; - break; - } + int found = 0; + for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) { + if (ssl_cipher_is_deprecated(cipher)) { + ++found; } - EXPECT_TRUE(found); } + EXPECT_EQ(found, test.expected_included_deprecated_count); } }
diff --git a/ssl/test/runner/cipher_suite_tests.go b/ssl/test/runner/cipher_suite_tests.go index 26b7114..01a0ecb 100644 --- a/ssl/test/runner/cipher_suite_tests.go +++ b/ssl/test/runner/cipher_suite_tests.go
@@ -38,6 +38,7 @@ {"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, {"ECDHE_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, {"ECDHE_RSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, + {"ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}, {"ECDHE_RSA_WITH_AES_128_CBC_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, {"ECDHE_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, {"ECDHE_RSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index 01dbea0..dbf5ab8 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc
@@ -2006,7 +2006,10 @@ SSL_CTX_set0_buffer_pool(ssl_ctx.get(), BufferPool()); - std::string cipher_list = "ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; + std::string cipher_list = "ALL"; + // Explicitly add deprecated ciphers that are otherwise not included. + cipher_list += ":TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; + cipher_list += ":TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; if (!cipher.empty()) { cipher_list = cipher; SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);