static S2N_RESULT s2n_check_kem()

in tls/s2n_kex.c [70:117]


static S2N_RESULT s2n_check_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
{
    RESULT_ENSURE_REF(cipher_suite);
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(is_supported);

    /* If any of the necessary conditions are not met, we will return early and indicate KEM is not supported. */
    *is_supported = false;

    const struct s2n_kem_preferences *kem_preferences = NULL;
    RESULT_GUARD_POSIX(s2n_connection_get_kem_preferences(conn, &kem_preferences));
    RESULT_ENSURE_REF(kem_preferences);

    if (!s2n_pq_is_enabled() || kem_preferences->kem_count == 0) {
        return S2N_RESULT_OK;
    }

    const struct s2n_iana_to_kem *supported_params = NULL;
    if (s2n_cipher_suite_to_kem(cipher_suite->iana_value, &supported_params) != S2N_SUCCESS) {
        return S2N_RESULT_OK;
    }

    RESULT_ENSURE_REF(supported_params);
    if (supported_params->kem_count == 0) {
        return S2N_RESULT_OK;
    }

    struct s2n_blob *client_kem_pref_list = &(conn->kex_params.client_pq_kem_extension);
    const struct s2n_kem *chosen_kem = NULL;
    if (client_kem_pref_list == NULL || client_kem_pref_list->data == NULL) {
        /* If the client did not send a PQ KEM extension, then the server can pick its preferred parameter */
        if (s2n_choose_kem_without_peer_pref_list(
                    cipher_suite->iana_value, kem_preferences->kems, kem_preferences->kem_count, &chosen_kem)
                != S2N_SUCCESS) {
            return S2N_RESULT_OK;
        }
    } else {
        /* If the client did send a PQ KEM extension, then the server must find a mutually supported parameter. */
        if (s2n_choose_kem_with_peer_pref_list(
                    cipher_suite->iana_value, client_kem_pref_list, kem_preferences->kems, kem_preferences->kem_count, &chosen_kem)
                != S2N_SUCCESS) {
            return S2N_RESULT_OK;
        }
    }

    *is_supported = chosen_kem != NULL;
    return S2N_RESULT_OK;
}