int s2n_conn_update_required_handshake_hashes()

in tls/s2n_handshake.c [141:181]


int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn)
{
    POSIX_ENSURE_REF(conn);
    POSIX_ENSURE_REF(conn->secure);

    /* Clear all of the required hashes */
    memset(conn->handshake.required_hash_algs, 0, sizeof(conn->handshake.required_hash_algs));

    message_type_t handshake_message = s2n_conn_get_current_message_type(conn);
    const uint8_t client_cert_verify_done = (handshake_message >= CLIENT_CERT_VERIFY) ? 1 : 0;
    s2n_cert_auth_type client_cert_auth_type;
    POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));

    /* If client authentication is possible, all hashes are needed until we're past CLIENT_CERT_VERIFY. */
    if ((client_cert_auth_type != S2N_CERT_AUTH_NONE) && !client_cert_verify_done) {
        POSIX_GUARD(s2n_handshake_require_all_hashes(&conn->handshake));
        return S2N_SUCCESS;
    }

    /* We don't need all of the hashes. Set the hash alg(s) required for the PRF */
    switch (conn->actual_protocol_version) {
        case S2N_SSLv3:
        case S2N_TLS10:
        case S2N_TLS11:
            POSIX_GUARD(s2n_handshake_require_hash(&conn->handshake, S2N_HASH_MD5));
            POSIX_GUARD(s2n_handshake_require_hash(&conn->handshake, S2N_HASH_SHA1));
            break;
        case S2N_TLS12:
            /* fall through */
        case S2N_TLS13: {
            /* For TLS 1.2 and TLS 1.3, the cipher suite defines the PRF hash alg */
            s2n_hmac_algorithm prf_alg = conn->secure->cipher_suite->prf_alg;
            s2n_hash_algorithm hash_alg;
            POSIX_GUARD(s2n_hmac_hash_alg(prf_alg, &hash_alg));
            POSIX_GUARD(s2n_handshake_require_hash(&conn->handshake, hash_alg));
            break;
        }
    }

    return S2N_SUCCESS;
}