/**
         * Transform a SRTCP packet into a RTCP packet.
         * This method is called when a SRTCP packet was received.
         *
         * Operations done by the this operation include:
         * Authentication check, Packet replay check and decryption.
         *
         * Both encryption and authentication functionality can be turned off
         * as long as the SRTPPolicy used in this SRTPCryptoContext requires no
         * encryption and no authentication. Then the packet will be sent out
         * untouched. However this is not encouraged. If no SRTCP feature is enabled,
         * then we shall not use SRTP TransformConnector. We should use the original
         * method (RTPManager managed transportation) instead.
         *
         * @param pkt the received RTCP packet
         * @return true if the packet can be accepted
         *         false if authentication or replay check failed
         */
        public bool ReverseTransformPacket(RawPacket pkt)
        {
            bool decrypt    = false;
            int  tagLength  = policy.AuthTagLength;
            int  indexEflag = pkt.GetSRTCPIndex(tagLength);

            if ((indexEflag & 0x80000000) == 0x80000000)
            {
                decrypt = true;
            }

            int index = (int)(indexEflag & ~0x80000000);

            /* Replay control */
            if (!CheckReplay(index))
            {
                return(false);
            }

            /* Authenticate the packet */
            if (policy.AuthType != SrtpPolicy.NULL_AUTHENTICATION)
            {
                // get original authentication data and store in tempStore
                pkt.ReadRegionToBuff(pkt.GetLength() - tagLength, tagLength, tempStore);

                // Shrink packet to remove the authentication tag and index
                // because this is part of authenticated data
                pkt.shrink(tagLength + 4);

                // compute, then save authentication in tagStore
                AuthenticatePacket(pkt, indexEflag);

                for (int i = 0; i < tagLength; i++)
                {
                    if ((tempStore[i] & 0xff) == (tagStore[i] & 0xff))
                    {
                        continue;
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            if (decrypt)
            {
                /* Decrypt the packet using Counter Mode encryption */
                if (policy.EncType == SrtpPolicy.AESCM_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISH_ENCRYPTION)
                {
                    ProcessPacketAESCM(pkt, index);
                }

                /* Decrypt the packet using F8 Mode encryption */
                else if (policy.EncType == SrtpPolicy.AESF8_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISHF8_ENCRYPTION)
                {
                    ProcessPacketAESF8(pkt, index);
                }
            }
            Update(index);
            return(true);
        }