예제 #1
0
        /**
         * Perform F8 Mode AES encryption / decryption
         *
         * @param pkt the RTP packet to be encrypted / decrypted
         */
        public void ProcessPacketAESF8(RawPacket pkt, int index)
        {
            // byte[] iv = new byte[16];

            // 4 bytes of the iv are zero
            // the first byte of the RTP header is not used.
            ivStore[0] = 0;
            ivStore[1] = 0;
            ivStore[2] = 0;
            ivStore[3] = 0;

            // Need the encryption flag
            index = (int)(index | 0x80000000);

            // set the index and the encrypt flag in network order into IV
            ivStore[4] = (byte)(index >> 24);
            ivStore[5] = (byte)(index >> 16);
            ivStore[6] = (byte)(index >> 8);
            ivStore[7] = (byte)index;

            // The fixed header follows and fills the rest of the IV
            MemoryStream buf = pkt.GetBuffer();

            buf.Position = 0;
            buf.Read(ivStore, 8, 8);

            // Encrypted part excludes fixed header (8 bytes), index (4 bytes), and
            // authentication tag (variable according to policy)
            int payloadOffset = 8;
            int payloadLength = pkt.GetLength() - (4 + policy.AuthTagLength);

            SrtpCipherF8.Process(cipher, pkt.GetBuffer(), payloadOffset, payloadLength, ivStore, cipherF8);
        }
예제 #2
0
        /**
         * Authenticate a packet.
         *
         * Calculated authentication tag is stored in tagStore area.
         *
         * @param pkt the RTP packet to be authenticated
         */
        private void AuthenticatePacket(RawPacket pkt, int index)
        {
            MemoryStream buf = pkt.GetBuffer();

            buf.Position = 0;
            int len = pkt.GetLength();

            buf.Read(tempBuffer, 0, len);

            mac.BlockUpdate(tempBuffer, 0, len);
            rbStore[0] = (byte)(index >> 24);
            rbStore[1] = (byte)(index >> 16);
            rbStore[2] = (byte)(index >> 8);
            rbStore[3] = (byte)index;
            mac.BlockUpdate(rbStore, 0, rbStore.Length);
            mac.DoFinal(tagStore, 0);
        }
예제 #3
0
        /**
         * Perform Counter Mode AES encryption / decryption
         * @param pkt the RTP packet to be encrypted / decrypted
         */
        public void ProcessPacketAESCM(RawPacket pkt, int index)
        {
            long ssrc = pkt.GetRTCPSSRC();

            /* Compute the CM IV (refer to chapter 4.1.1 in RFC 3711):
             *
             * k_s   XX XX XX XX XX XX XX XX XX XX XX XX XX XX
             * SSRC              XX XX XX XX
             * index                               XX XX XX XX
             * ------------------------------------------------------XOR
             * IV    XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00
             *        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
             */
            ivStore[0] = saltKey[0];
            ivStore[1] = saltKey[1];
            ivStore[2] = saltKey[2];
            ivStore[3] = saltKey[3];

            // The shifts transform the ssrc and index into network order
            ivStore[4] = (byte)(((ssrc >> 24) & 0xff) ^ this.saltKey[4]);
            ivStore[5] = (byte)(((ssrc >> 16) & 0xff) ^ this.saltKey[5]);
            ivStore[6] = (byte)(((ssrc >> 8) & 0xff) ^ this.saltKey[6]);
            ivStore[7] = (byte)((ssrc & 0xff) ^ this.saltKey[7]);

            ivStore[8] = saltKey[8];
            ivStore[9] = saltKey[9];

            ivStore[10] = (byte)(((index >> 24) & 0xff) ^ this.saltKey[10]);
            ivStore[11] = (byte)(((index >> 16) & 0xff) ^ this.saltKey[11]);
            ivStore[12] = (byte)(((index >> 8) & 0xff) ^ this.saltKey[12]);
            ivStore[13] = (byte)((index & 0xff) ^ this.saltKey[13]);

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

            // Encrypted part excludes fixed header (8 bytes)
            int payloadOffset = 8;
            int payloadLength = pkt.GetLength() - payloadOffset;

            cipherCtr.Process(cipher, pkt.GetBuffer(), payloadOffset, payloadLength, ivStore);
        }
예제 #4
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);
        }
예제 #5
0
        /**
         * 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);
        }