def _tls_hmac_verify(self, hdr, msg, mac):
        """
        Provided with the record header, the TLSCompressed.fragment and the
        HMAC, return True if the HMAC is correct. If we could not compute the
        HMAC because the key was missing, there is no sense in verifying
        anything, thus we also return True.

        Meant to be used with a block cipher or a stream cipher.
        It would fail with an AEAD cipher, because rcs.hmac would be None.
        See RFC 5246, section 6.2.3.
        """
        read_seq_num = struct.pack("!Q", self.tls_session.rcs.seq_num)
        self.tls_session.rcs.seq_num += 1

        mac_len = self.tls_session.rcs.mac_len
        if mac_len == 0:            # should be TLS_NULL_WITH_NULL_NULL
            return True
        if len(mac) != mac_len:
            return False

        alg = self.tls_session.rcs.hmac
        version = struct.unpack("!H", hdr[1:3])[0]
        try:
            if version > 0x300:
                h = alg.digest(read_seq_num + hdr + msg)
            elif version == 0x300:
                h = alg.digest_sslv3(read_seq_num + hdr[:1] + hdr[3:5] + msg)
            else:
                raise Exception("Unrecognized version.")
        except HMACError:
            h = mac
        return h == mac
Provided with the record header, the TLSCompressed.fragment and the
        HMAC, return True if the HMAC is correct. If we could not compute the
        HMAC because the key was missing, there is no sense in verifying
        anything, thus we also return True.

        Meant to be used with a block cipher or a stream cipher.
        It would fail with an AEAD cipher, because rcs.hmac would be None.
        See RFC 5246, section 6.2.3.