/** * 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); }