in tls/s2n_cipher_suites.c [1178:1277]
static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire, uint32_t count, uint32_t cipher_suite_len)
{
uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
struct s2n_cipher_suite *higher_vers_match = NULL;
/* RFC 7507 - If client is attempting to negotiate a TLS Version that is lower than the highest supported server
* version, and the client cipher list contains TLS_FALLBACK_SCSV, then the server must abort the connection since
* TLS_FALLBACK_SCSV should only be present when the client previously failed to negotiate a higher TLS version.
*/
if (conn->client_protocol_version < conn->server_protocol_version) {
uint8_t fallback_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_FALLBACK_SCSV };
if (s2n_wire_ciphers_contain(fallback_scsv, wire, count, cipher_suite_len)) {
conn->closed = 1;
POSIX_BAIL(S2N_ERR_FALLBACK_DETECTED);
}
}
/* RFC5746 Section 3.6: A server must check if TLS_EMPTY_RENEGOTIATION_INFO_SCSV is included */
if (s2n_wire_ciphers_contain(renegotiation_info_scsv, wire, count, cipher_suite_len)) {
conn->secure_renegotiation = 1;
}
const struct s2n_security_policy *security_policy;
POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
/* s2n supports only server order */
for (int i = 0; i < security_policy->cipher_preferences->count; i++) {
const uint8_t *ours = security_policy->cipher_preferences->suites[i]->iana_value;
if (s2n_wire_ciphers_contain(ours, wire, count, cipher_suite_len)) {
/* We have a match */
struct s2n_cipher_suite *match = security_policy->cipher_preferences->suites[i];
/* Never use TLS1.3 ciphers on a pre-TLS1.3 connection, and vice versa */
if ((conn->actual_protocol_version >= S2N_TLS13) != (match->minimum_required_tls_version >= S2N_TLS13)) {
continue;
}
/* If connection is for SSLv3, use SSLv3 version of suites */
if (conn->client_protocol_version == S2N_SSLv3) {
match = match->sslv3_cipher_suite;
}
/* Skip the suite if we don't have an available implementation */
if (!match->available) {
continue;
}
/* Make sure the cipher is valid for available certs */
if (s2n_is_cipher_suite_valid_for_auth(conn, match) != S2N_SUCCESS) {
continue;
}
/* TLS 1.3 does not include key exchange in cipher suites */
if (match->minimum_required_tls_version < S2N_TLS13) {
/* If the kex is not supported continue to the next candidate */
bool kex_supported = false;
POSIX_GUARD_RESULT(s2n_kex_supported(match, conn, &kex_supported));
if (!kex_supported) {
continue;
}
/* If the kex is not configured correctly continue to the next candidate */
if (s2n_result_is_error(s2n_configure_kex(match, conn))) {
continue;
}
}
/**
*= https://tools.ietf.org/rfc/rfc8446#section-4.2.11
*# The server MUST ensure that it selects a compatible PSK
*# (if any) and cipher suite.
**/
if (conn->psk_params.chosen_psk != NULL) {
if (match->prf_alg != conn->psk_params.chosen_psk->hmac_alg) {
continue;
}
}
/* Don't immediately choose a cipher the connection shouldn't be able to support */
if (conn->actual_protocol_version < match->minimum_required_tls_version) {
if (!higher_vers_match) {
higher_vers_match = match;
}
continue;
}
conn->secure.cipher_suite = match;
return S2N_SUCCESS;
}
}
/* Settle for a cipher with a higher required proto version, if it was set */
if (higher_vers_match) {
conn->secure.cipher_suite = higher_vers_match;
return S2N_SUCCESS;
}
POSIX_BAIL(S2N_ERR_CIPHER_NOT_SUPPORTED);
}