Provided with a TLSCiphertext instance c, the function applies AEAD
    cipher alg auth_decrypt function to c.data (and additional data)
    in order to authenticate the data and decrypt c.data. When those
    steps succeed, the result is a newly created TLSCompressed instance.
    On error, None is returned. Note that it is the caller's responsibility to
    increment read_seq_num afterwards.

def _tls_aead_auth_decrypt(alg, c, read_seq_num):
    """
    Provided with a TLSCiphertext instance c, the function applies AEAD
    cipher alg auth_decrypt function to c.data (and additional data)
    in order to authenticate the data and decrypt c.data. When those
    steps succeed, the result is a newly created TLSCompressed instance.
    On error, None is returned. Note that it is the caller's responsibility to
    increment read_seq_num afterwards.
    """
    # 'Deduce' TLSCompressed length from TLSCiphertext length
    # There is actually no guaranty of this equality, but this is defined as
    # such in TLS 1.2 specifications, and it works for GCM and CCM at least.
    #
    plen = c.len - getattr(alg, "nonce_explicit_len", 0) - alg.tag_len
    read_seq_num = struct.pack("!Q", read_seq_num)
    A = read_seq_num + struct.pack('!BHH', c.type, c.version, plen)

    p = TLSCompressed()
    p.type = c.type
    p.version = c.version
    p.len = plen
    p.data = alg.auth_decrypt(A, c.data, read_seq_num)

    if p.data is None:  # Verification failed.
        return None
    return p