Add back support for TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
This TLS 1.2 algorithm is substantially inferior to AES-GCM and should
never be used. It will not be available unless configured by name.
However, in can be used to provide backwards-compatibility with devices
that cannot be updated if so needed.
Change-Id: I1fd78efeb33aceca76ec2e7cb76b70f761ed1af8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/59585
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Auto-Submit: Adam Langley <agl@google.com>
diff --git a/crypto/cipher_extra/cipher_test.cc b/crypto/cipher_extra/cipher_test.cc
index 4c8c142..6101ef9 100644
--- a/crypto/cipher_extra/cipher_test.cc
+++ b/crypto/cipher_extra/cipher_test.cc
@@ -623,6 +623,53 @@
}
}
+TEST(CipherTest, SHA256WithSecretSuffix) {
+ uint8_t buf[SHA256_CBLOCK * 4];
+ RAND_bytes(buf, sizeof(buf));
+ // Hashing should run in time independent of the bytes.
+ CONSTTIME_SECRET(buf, sizeof(buf));
+
+ // Exhaustively testing interesting cases in this function is cubic in the
+ // block size, so we test in 3-byte increments.
+ constexpr size_t kSkip = 3;
+ // This value should be less than 8 to test the edge case when the 8-byte
+ // length wraps to the next block.
+ static_assert(kSkip < 8, "kSkip is too large");
+
+ // |EVP_sha256_final_with_secret_suffix| is sensitive to the public length of
+ // the partial block previously hashed. In TLS, this is the HMAC prefix, the
+ // header, and the public minimum padding length.
+ for (size_t prefix = 0; prefix < SHA256_CBLOCK; prefix += kSkip) {
+ SCOPED_TRACE(prefix);
+ // The first block is treated differently, so we run with up to three
+ // blocks of length variability.
+ for (size_t max_len = 0; max_len < 3 * SHA256_CBLOCK; max_len += kSkip) {
+ SCOPED_TRACE(max_len);
+ for (size_t len = 0; len <= max_len; len += kSkip) {
+ SCOPED_TRACE(len);
+
+ uint8_t expected[SHA256_DIGEST_LENGTH];
+ SHA256(buf, prefix + len, expected);
+ CONSTTIME_DECLASSIFY(expected, sizeof(expected));
+
+ // Make a copy of the secret length to avoid interfering with the loop.
+ size_t secret_len = len;
+ CONSTTIME_SECRET(&secret_len, sizeof(secret_len));
+
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, buf, prefix);
+ uint8_t computed[SHA256_DIGEST_LENGTH];
+ ASSERT_TRUE(EVP_sha256_final_with_secret_suffix(
+ &ctx, computed, buf + prefix, secret_len, max_len));
+
+ CONSTTIME_DECLASSIFY(computed, sizeof(computed));
+ EXPECT_EQ(Bytes(expected), Bytes(computed));
+ }
+ }
+ }
+}
+
TEST(CipherTest, GetCipher) {
const EVP_CIPHER *cipher = EVP_get_cipherbynid(NID_aes_128_gcm);
ASSERT_TRUE(cipher);
diff --git a/crypto/cipher_extra/e_tls.c b/crypto/cipher_extra/e_tls.c
index 00b4824..c462a2b 100644
--- a/crypto/cipher_extra/e_tls.c
+++ b/crypto/cipher_extra/e_tls.c
@@ -400,6 +400,14 @@
EVP_sha1(), 1);
}
+static int aead_aes_128_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx,
+ const uint8_t *key, size_t key_len,
+ size_t tag_len,
+ enum evp_aead_direction_t dir) {
+ return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(),
+ EVP_sha256(), 0);
+}
+
static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len,
enum evp_aead_direction_t dir) {
@@ -476,6 +484,23 @@
aead_tls_tag_len,
};
+static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
+ SHA256_DIGEST_LENGTH + 16, // key len (SHA256 + AES128)
+ 16, // nonce len (IV)
+ 16 + SHA256_DIGEST_LENGTH, // overhead (padding + SHA256)
+ SHA256_DIGEST_LENGTH, // max tag length
+ 0, // seal_scatter_supports_extra_in
+
+ NULL, // init
+ aead_aes_128_cbc_sha256_tls_init,
+ aead_tls_cleanup,
+ aead_tls_open,
+ aead_tls_seal_scatter,
+ NULL, // open_gather
+ NULL, // get_iv
+ aead_tls_tag_len,
+};
+
static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
SHA_DIGEST_LENGTH + 32, // key len (SHA1 + AES256)
16, // nonce len (IV)
@@ -552,6 +577,10 @@
return &aead_aes_128_cbc_sha1_tls_implicit_iv;
}
+const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void) {
+ return &aead_aes_128_cbc_sha256_tls;
+}
+
const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void) {
return &aead_aes_256_cbc_sha1_tls;
}
diff --git a/crypto/cipher_extra/internal.h b/crypto/cipher_extra/internal.h
index 76a0314..39ab950 100644
--- a/crypto/cipher_extra/internal.h
+++ b/crypto/cipher_extra/internal.h
@@ -109,6 +109,14 @@
SHA_CTX *ctx, uint8_t out[SHA_DIGEST_LENGTH], const uint8_t *in, size_t len,
size_t max_len);
+// EVP_sha256_final_with_secret_suffix acts like
+// |EVP_sha1_final_with_secret_suffix|, but for SHA-256.
+//
+// This function is exported for unit tests.
+OPENSSL_EXPORT int EVP_sha256_final_with_secret_suffix(
+ SHA256_CTX *ctx, uint8_t out[SHA256_DIGEST_LENGTH], const uint8_t *in,
+ size_t len, size_t max_len);
+
// EVP_tls_cbc_digest_record computes the MAC of a decrypted, padded TLS
// record.
//
diff --git a/crypto/cipher_extra/tls_cbc.c b/crypto/cipher_extra/tls_cbc.c
index e1e95d4..ac6ca43 100644
--- a/crypto/cipher_extra/tls_cbc.c
+++ b/crypto/cipher_extra/tls_cbc.c
@@ -267,24 +267,115 @@
return 1;
}
-int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) {
- return EVP_MD_type(md) == NID_sha1;
-}
-
-int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
- size_t *md_out_size, const uint8_t header[13],
- const uint8_t *data, size_t data_size,
- size_t data_plus_mac_plus_padding_size,
- const uint8_t *mac_secret,
- unsigned mac_secret_length) {
- if (EVP_MD_type(md) != NID_sha1) {
- // EVP_tls_cbc_record_digest_supported should have been called first to
- // check that the hash function is supported.
- assert(0);
- *md_out_size = 0;
- return 0;
+int EVP_sha256_final_with_secret_suffix(SHA256_CTX *ctx,
+ uint8_t out[SHA256_DIGEST_LENGTH],
+ const uint8_t *in, size_t len,
+ size_t max_len) {
+ // Bound the input length so |total_bits| below fits in four bytes. This is
+ // redundant with TLS record size limits. This also ensures |input_idx| below
+ // does not overflow.
+ size_t max_len_bits = max_len << 3;
+ if (ctx->Nh != 0 ||
+ (max_len_bits >> 3) != max_len || // Overflow
+ ctx->Nl + max_len_bits < max_len_bits ||
+ ctx->Nl + max_len_bits > UINT32_MAX) {
+ return 0;
}
+ // We need to hash the following into |ctx|:
+ //
+ // - ctx->data[:ctx->num]
+ // - in[:len]
+ // - A 0x80 byte
+ // - However many zero bytes are needed to pad up to a block.
+ // - Eight bytes of length.
+ size_t num_blocks = (ctx->num + len + 1 + 8 + SHA256_CBLOCK - 1) >> 6;
+ size_t last_block = num_blocks - 1;
+ size_t max_blocks = (ctx->num + max_len + 1 + 8 + SHA256_CBLOCK - 1) >> 6;
+
+ // The bounds above imply |total_bits| fits in four bytes.
+ size_t total_bits = ctx->Nl + (len << 3);
+ uint8_t length_bytes[4];
+ length_bytes[0] = (uint8_t)(total_bits >> 24);
+ length_bytes[1] = (uint8_t)(total_bits >> 16);
+ length_bytes[2] = (uint8_t)(total_bits >> 8);
+ length_bytes[3] = (uint8_t)total_bits;
+
+ // We now construct and process each expected block in constant-time.
+ uint8_t block[SHA256_CBLOCK] = {0};
+ uint32_t result[8] = {0};
+ // input_idx is the index into |in| corresponding to the current block.
+ // However, we allow this index to overflow beyond |max_len|, to simplify the
+ // 0x80 byte.
+ size_t input_idx = 0;
+ for (size_t i = 0; i < max_blocks; i++) {
+ // Fill |block| with data from the partial block in |ctx| and |in|. We copy
+ // as if we were hashing up to |max_len| and then zero the excess later.
+ size_t block_start = 0;
+ if (i == 0) {
+ OPENSSL_memcpy(block, ctx->data, ctx->num);
+ block_start = ctx->num;
+ }
+ if (input_idx < max_len) {
+ size_t to_copy = SHA256_CBLOCK - block_start;
+ if (to_copy > max_len - input_idx) {
+ to_copy = max_len - input_idx;
+ }
+ OPENSSL_memcpy(block + block_start, in + input_idx, to_copy);
+ }
+
+ // Zero any bytes beyond |len| and add the 0x80 byte.
+ for (size_t j = block_start; j < SHA256_CBLOCK; j++) {
+ // input[idx] corresponds to block[j].
+ size_t idx = input_idx + j - block_start;
+ // The barriers on |len| are not strictly necessary. However, without
+ // them, GCC compiles this code by incorporating |len| into the loop
+ // counter and subtracting it out later. This is still constant-time, but
+ // it frustrates attempts to validate this.
+ uint8_t is_in_bounds = constant_time_lt_8(idx, value_barrier_w(len));
+ uint8_t is_padding_byte = constant_time_eq_8(idx, value_barrier_w(len));
+ block[j] &= is_in_bounds;
+ block[j] |= 0x80 & is_padding_byte;
+ }
+
+ input_idx += SHA256_CBLOCK - block_start;
+
+ // Fill in the length if this is the last block.
+ crypto_word_t is_last_block = constant_time_eq_w(i, last_block);
+ for (size_t j = 0; j < 4; j++) {
+ block[SHA256_CBLOCK - 4 + j] |= is_last_block & length_bytes[j];
+ }
+
+ // Process the block and save the hash state if it is the final value.
+ SHA256_Transform(ctx, block);
+ for (size_t j = 0; j < 8; j++) {
+ result[j] |= is_last_block & ctx->h[j];
+ }
+ }
+
+ // Write the output.
+ for (size_t i = 0; i < 8; i++) {
+ CRYPTO_store_u32_be(out + 4 * i, result[i]);
+ }
+ return 1;
+}
+
+int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) {
+ switch (EVP_MD_type(md)) {
+ case NID_sha1:
+ case NID_sha256:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int tls_cbc_digest_record_sha1(uint8_t *md_out, size_t *md_out_size,
+ const uint8_t header[13],
+ const uint8_t *data, size_t data_size,
+ size_t data_plus_mac_plus_padding_size,
+ const uint8_t *mac_secret,
+ unsigned mac_secret_length) {
if (mac_secret_length > SHA_CBLOCK) {
// HMAC pads small keys with zeros and hashes large keys down. This function
// should never reach the large key case.
@@ -336,3 +427,88 @@
*md_out_size = SHA_DIGEST_LENGTH;
return 1;
}
+
+static int tls_cbc_digest_record_sha256(uint8_t *md_out, size_t *md_out_size,
+ const uint8_t header[13],
+ const uint8_t *data, size_t data_size,
+ size_t data_plus_mac_plus_padding_size,
+ const uint8_t *mac_secret,
+ unsigned mac_secret_length) {
+ if (mac_secret_length > SHA256_CBLOCK) {
+ // HMAC pads small keys with zeros and hashes large keys down. This function
+ // should never reach the large key case.
+ assert(0);
+ return 0;
+ }
+
+ // Compute the initial HMAC block.
+ uint8_t hmac_pad[SHA256_CBLOCK];
+ OPENSSL_memset(hmac_pad, 0, sizeof(hmac_pad));
+ OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length);
+ for (size_t i = 0; i < SHA256_CBLOCK; i++) {
+ hmac_pad[i] ^= 0x36;
+ }
+
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, hmac_pad, SHA256_CBLOCK);
+ SHA256_Update(&ctx, header, 13);
+
+ // There are at most 256 bytes of padding, so we can compute the public
+ // minimum length for |data_size|.
+ size_t min_data_size = 0;
+ if (data_plus_mac_plus_padding_size > SHA256_DIGEST_LENGTH + 256) {
+ min_data_size =
+ data_plus_mac_plus_padding_size - SHA256_DIGEST_LENGTH - 256;
+ }
+
+ // Hash the public minimum length directly. This reduces the number of blocks
+ // that must be computed in constant-time.
+ SHA256_Update(&ctx, data, min_data_size);
+
+ // Hash the remaining data without leaking |data_size|.
+ uint8_t mac_out[SHA256_DIGEST_LENGTH];
+ if (!EVP_sha256_final_with_secret_suffix(
+ &ctx, mac_out, data + min_data_size, data_size - min_data_size,
+ data_plus_mac_plus_padding_size - min_data_size)) {
+ return 0;
+ }
+
+ // Complete the HMAC in the standard manner.
+ SHA256_Init(&ctx);
+ for (size_t i = 0; i < SHA256_CBLOCK; i++) {
+ hmac_pad[i] ^= 0x6a;
+ }
+
+ SHA256_Update(&ctx, hmac_pad, SHA256_CBLOCK);
+ SHA256_Update(&ctx, mac_out, SHA256_DIGEST_LENGTH);
+ SHA256_Final(md_out, &ctx);
+ *md_out_size = SHA256_DIGEST_LENGTH;
+ return 1;
+}
+
+int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
+ size_t *md_out_size, const uint8_t header[13],
+ const uint8_t *data, size_t data_size,
+ size_t data_plus_mac_plus_padding_size,
+ const uint8_t *mac_secret,
+ unsigned mac_secret_length) {
+ switch (EVP_MD_type(md)) {
+ case NID_sha1:
+ return tls_cbc_digest_record_sha1(
+ md_out, md_out_size, header, data, data_size,
+ data_plus_mac_plus_padding_size, mac_secret, mac_secret_length);
+
+ case NID_sha256:
+ return tls_cbc_digest_record_sha256(
+ md_out, md_out_size, header, data, data_size,
+ data_plus_mac_plus_padding_size, mac_secret, mac_secret_length);
+
+ default:
+ // EVP_tls_cbc_record_digest_supported should have been called first to
+ // check that the hash function is supported.
+ assert(0);
+ *md_out_size = 0;
+ return 0;
+ }
+}
diff --git a/include/openssl/aead.h b/include/openssl/aead.h
index 7aa0b44..376bff1 100644
--- a/include/openssl/aead.h
+++ b/include/openssl/aead.h
@@ -400,6 +400,8 @@
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void);
+
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void);
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index 724d580..772fb87 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -408,6 +408,8 @@
#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_RSA_WITH_AES_128_CBC_SHA256 0x0300C027
+
#define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015
#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016
#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017
@@ -518,6 +520,8 @@
#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_RSA_WITH_AES_128_CBC_SHA256 "ECDHE-RSA-AES128-SHA256"
+
#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA"
#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA"
#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA"
diff --git a/ssl/internal.h b/ssl/internal.h
index 9ba2b14..1e6da21 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -553,8 +553,9 @@
// Bits for |algorithm_mac| (symmetric authentication).
#define SSL_SHA1 0x00000001u
+#define SSL_SHA256 0x00000002u
// SSL_AEAD is set for all AEADs.
-#define SSL_AEAD 0x00000002u
+#define SSL_AEAD 0x00000004u
// Bits for |algorithm_prf| (handshake digest).
#define SSL_HANDSHAKE_MAC_DEFAULT 0x1
@@ -672,6 +673,9 @@
bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id,
enum ssl_compliance_policy_t policy);
+// ssl_cipher_is_deprecated returns true if |cipher| is deprecated.
+OPENSSL_EXPORT bool ssl_cipher_is_deprecated(const SSL_CIPHER *cipher);
+
// Transcript layer.
diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc
index 2f8fc2a..0d4206c 100644
--- a/ssl/ssl_cipher.cc
+++ b/ssl/ssl_cipher.cc
@@ -335,6 +335,18 @@
SSL_HANDSHAKE_MAC_DEFAULT,
},
+ // Cipher C027
+ {
+ TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_HANDSHAKE_MAC_SHA256,
+ },
+
// GCM based TLS v1.2 ciphersuites from RFC 5289
// Cipher C02B
@@ -626,6 +638,14 @@
}
*out_mac_secret_len = SHA_DIGEST_LENGTH;
+ } else if (cipher->algorithm_mac == SSL_SHA256) {
+ if (cipher->algorithm_enc == SSL_AES128) {
+ *out_aead = EVP_aead_aes_128_cbc_sha256_tls();
+ } else {
+ return false;
+ }
+
+ *out_mac_secret_len = SHA256_DIGEST_LENGTH;
} else {
return false;
}
@@ -748,9 +768,9 @@
sk_SSL_CIPHER_delete(ciphers.get(), index);
}
-static bool ssl_cipher_is_deprecated(const SSL_CIPHER *cipher) {
+bool ssl_cipher_is_deprecated(const SSL_CIPHER *cipher) {
// TODO(crbug.com/boringssl/599): Deprecate 3DES.
- return false;
+ return cipher->id == TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
}
// ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its
@@ -1138,6 +1158,7 @@
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA & 0xffff,
TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA & 0xffff,
TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA & 0xffff,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 & 0xffff,
TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 & 0xffff,
TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 & 0xffff,
TLS1_CK_RSA_WITH_AES_128_SHA & 0xffff,
@@ -1380,6 +1401,8 @@
return NID_undef;
case SSL_SHA1:
return NID_sha1;
+ case SSL_SHA256:
+ return NID_sha256;
}
assert(0);
return NID_undef;
@@ -1628,6 +1651,10 @@
mac = "SHA1";
break;
+ case SSL_SHA256:
+ mac = "SHA256";
+ break;
+
case SSL_AEAD:
mac = "AEAD";
break;
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index 1a06ba8..a665ced 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -382,7 +382,7 @@
"[AES128-SHA | AES128-SHA256]",
};
-static const char *kMustNotIncludeNull[] = {
+static const char *kMustNotIncludeDeprecated[] = {
"ALL",
"DEFAULT",
"HIGH",
@@ -395,6 +395,11 @@
"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 CurveTest kCurveTests[] = {
{
"P-256",
@@ -578,7 +583,7 @@
ERR_clear_error();
}
- for (const char *rule : kMustNotIncludeNull) {
+ for (const char *rule : kMustNotIncludeDeprecated) {
SCOPED_TRACE(rule);
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
@@ -586,6 +591,25 @@
ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
+ 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));
+
+ bool found = false;
+ for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
+ if ((TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 & 0xffff) ==
+ SSL_CIPHER_get_protocol_id(cipher)) {
+ found = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(found);
}
}
}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index a4887af..86daca2 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -1843,6 +1843,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_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},
{"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index aa15320..b204491 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -1391,7 +1391,7 @@
SSL_CTX_set0_buffer_pool(ssl_ctx.get(), g_pool);
- std::string cipher_list = "ALL";
+ std::string cipher_list = "ALL: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);