예제 #1
0
        /**
         * Perform Counter Mode AES encryption / decryption
         *
         * @param pkt
         *            the RTP packet to be encrypted / decrypted
         */
        public void ProcessPacketAESCM(RawPacket pkt)
        {
            long ssrc  = pkt.GetSSRC();
            int  seqNo = pkt.GetSequenceNumber();

#pragma warning disable CS0675 // Bitwise-or operator used on a sign-extended operand
            long index = ((long)roc << 16) | seqNo;
#pragma warning restore CS0675 // Bitwise-or operator used on a sign-extended operand

            ivStore[0] = saltKey[0];
            ivStore[1] = saltKey[1];
            ivStore[2] = saltKey[2];
            ivStore[3] = saltKey[3];

            int i;
            for (i = 4; i < 8; i++)
            {
                ivStore[i] = (byte)((0xFF & (ssrc >> ((7 - i) * 8))) ^ this.saltKey[i]);
            }

            for (i = 8; i < 14; i++)
            {
                ivStore[i] = (byte)((0xFF & (byte)(index >> ((13 - i) * 8))) ^ this.saltKey[i]);
            }

            ivStore[14] = ivStore[15] = 0;

            int payloadOffset = pkt.GetHeaderLength();
            int payloadLength = pkt.GetPayloadLength();

            cipherCtr.Process(cipher, pkt.GetBuffer(), payloadOffset, payloadLength, ivStore);
        }
예제 #2
0
        /**
         * Transform a RTP packet into a SRTP packet. This method is called when a
         * normal RTP packet ready to be sent.
         *
         * Operations done by the transformation may include: encryption, using
         * either Counter Mode encryption, or F8 Mode encryption, adding
         * authentication tag, currently HMC SHA1 method.
         *
         * Both encryption and authentication functionality can be turned off as
         * long as the SRTPPolicy used in this SRTPCryptoContext is 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 going to be sent out
         */
        public void TransformPacket(RawPacket pkt)
        {
            /* Encrypt the packet using Counter Mode encryption */
            if (policy.EncType == SrtpPolicy.AESCM_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISH_ENCRYPTION)
            {
                ProcessPacketAESCM(pkt);
            }
            else if (policy.EncType == SrtpPolicy.AESF8_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISHF8_ENCRYPTION)
            {
                /* Encrypt the packet using F8 Mode encryption */
                ProcessPacketAESF8(pkt);
            }

            /* Authenticate the packet */
            if (policy.AuthType != SrtpPolicy.NULL_AUTHENTICATION)
            {
                AuthenticatePacketHMCSHA1(pkt, roc);
                pkt.Append(tagStore, policy.AuthTagLength);
            }

            /* Update the ROC if necessary */
            int seqNo = pkt.GetSequenceNumber();

            if (seqNo == 0xFFFF)
            {
                roc++;
            }
        }
예제 #3
0
        /**
         * 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);
        }