Factor out TLS cipher selection to ssl_choose_tls_cipher.
This is factored out since ESNI will need to do its own cipher selection.
Bug: 275
Change-Id: Id87fd91272fbcd9098b3f2a9caa78a2129b154b5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/36544
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc
index 8fb0d5c..4ebea5b 100644
--- a/ssl/tls13_server.cc
+++ b/ssl/tls13_server.cc
@@ -103,78 +103,15 @@
return 1;
}
-// CipherScorer produces a "score" for each possible cipher suite offered by
-// the client.
-class CipherScorer {
- public:
- CipherScorer(uint16_t group_id)
- : aes_is_fine_(EVP_has_aes_hardware()),
- security_128_is_fine_(group_id != SSL_CURVE_CECPQ2 &&
- group_id != SSL_CURVE_CECPQ2b) {}
-
- typedef std::tuple<bool, bool, bool> Score;
-
- // MinScore returns a |Score| that will compare less than the score of all
- // cipher suites.
- Score MinScore() const {
- return Score(false, false, false);
- }
-
- Score Evaluate(const SSL_CIPHER *a) const {
- return Score(
- // Something is always preferable to nothing.
- true,
- // Either 128-bit is fine, or 256-bit is preferred.
- security_128_is_fine_ || a->algorithm_enc != SSL_AES128GCM,
- // Either AES is fine, or else ChaCha20 is preferred.
- aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305);
- }
-
- private:
- const bool aes_is_fine_;
- const bool security_128_is_fine_;
-};
-
static const SSL_CIPHER *choose_tls13_cipher(
const SSL *ssl, const SSL_CLIENT_HELLO *client_hello, uint16_t group_id) {
- if (client_hello->cipher_suites_len % 2 != 0) {
- return nullptr;
- }
-
CBS cipher_suites;
CBS_init(&cipher_suites, client_hello->cipher_suites,
client_hello->cipher_suites_len);
const uint16_t version = ssl_protocol_version(ssl);
- const SSL_CIPHER *best = nullptr;
- CipherScorer scorer(group_id);
- CipherScorer::Score best_score = scorer.MinScore();
-
- while (CBS_len(&cipher_suites) > 0) {
- uint16_t cipher_suite;
- if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
- return nullptr;
- }
-
- // Limit to TLS 1.3 ciphers we know about.
- const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
- if (candidate == nullptr ||
- SSL_CIPHER_get_min_version(candidate) > version ||
- SSL_CIPHER_get_max_version(candidate) < version) {
- continue;
- }
-
- const CipherScorer::Score candidate_score = scorer.Evaluate(candidate);
- // |candidate_score| must be larger to displace the current choice. That way
- // the client's order controls between ciphers with an equal score.
- if (candidate_score > best_score) {
- best = candidate;
- best_score = candidate_score;
- }
- }
-
- return best;
+ return ssl_choose_tls13_cipher(cipher_suites, version, group_id);
}
static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) {