/** * 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); }
/** * 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); }
/** * Perform F8 Mode AES encryption / decryption * * @param pkt * the RTP packet to be encrypted / decrypted */ public void ProcessPacketAESF8(RawPacket pkt) { // 11 bytes of the RTP header are the 11 bytes of the iv // the first byte of the RTP header is not used. MemoryStream buf = pkt.GetBuffer(); buf.Read(ivStore, (int)buf.Position, 12); ivStore[0] = 0; // set the ROC in network order into IV ivStore[12] = (byte)(this.roc >> 24); ivStore[13] = (byte)(this.roc >> 16); ivStore[14] = (byte)(this.roc >> 8); ivStore[15] = (byte)this.roc; int payloadOffset = pkt.GetHeaderLength(); int payloadLength = pkt.GetPayloadLength(); SrtpCipherF8.Process(cipher, pkt.GetBuffer(), payloadOffset, payloadLength, ivStore, cipherF8); }
/** * Authenticate a packet. Calculated authentication tag is returned. * * @param pkt * the RTP packet to be authenticated * @param rocIn * Roll-Over-Counter */ private void AuthenticatePacketHMCSHA1(RawPacket pkt, int rocIn) { MemoryStream buf = pkt.GetBuffer(); buf.Position = 0; int len = (int)buf.Length; buf.Read(tempBuffer, 0, len); mac.BlockUpdate(tempBuffer, 0, len); rbStore[0] = (byte)(rocIn >> 24); rbStore[1] = (byte)(rocIn >> 16); rbStore[2] = (byte)(rocIn >> 8); rbStore[3] = (byte)rocIn; mac.BlockUpdate(rbStore, 0, rbStore.Length); mac.DoFinal(tagStore, 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); }
/** * 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); }