/** * Transform a SRTP packet into a RTP packet. This method is called when a * SRTP packet is 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 SRTP feature is enabled, * then we shall not use SRTP TransformConnector. We should use the original * method (RTPManager managed transportation) instead. * * @param pkt * the RTP packet that is just received * @return true if the packet can be accepted false if the packet failed * authentication or failed replay check */ public bool ReverseTransformPacket(RawPacket pkt) { int seqNo = pkt.GetSequenceNumber(); if (!seqNumSet) { seqNumSet = true; seqNum = seqNo; } // Guess the SRTP index (48 bit), see rFC 3711, 3.3.1 // Stores the guessed roc in this.guessedROC long guessedIndex = GuessIndex(seqNo); // Replay control if (!CheckReplay(seqNo, guessedIndex)) { return(false); } // Authenticate packet if (policy.AuthType != SrtpPolicy.NULL_AUTHENTICATION) { int tagLength = policy.AuthTagLength; // get original authentication and store in tempStore pkt.ReadRegionToBuff(pkt.GetLength() - tagLength, tagLength, tempStore); pkt.shrink(tagLength); // save computed authentication in tagStore AuthenticatePacketHMCSHA1(pkt, guessedROC); for (int i = 0; i < tagLength; i++) { if ((tempStore[i] & 0xff) != (tagStore[i] & 0xff)) { return(false); } } } // Decrypt packet switch (policy.EncType) { case SrtpPolicy.AESCM_ENCRYPTION: case SrtpPolicy.TWOFISH_ENCRYPTION: // using Counter Mode encryption ProcessPacketAESCM(pkt); break; case SrtpPolicy.AESF8_ENCRYPTION: case SrtpPolicy.TWOFISHF8_ENCRYPTION: // using F8 Mode encryption ProcessPacketAESF8(pkt); break; default: return(false); } Update(seqNo, guessedIndex); return(true); }
/** * 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 authenicated 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); }