def readall(read_fn, sz):
    """Reads `sz` bytes using `read_fn`

    Raises `EOFError` if `read_fn` returned the empty byte array while reading
    all `sz` bytes.
    """
    buff = b''
    have = 0
    while have < sz:
        chunk = read_fn(sz - have)
        have += len(chunk)
        buff += chunk

        if len(chunk) == 0:
            raise EOFError

    return buff