public byte[] PackSrtpPacket(RtpPacket packet) { var offset = 0; var buffer = new byte[RtpPacket.BUFFER_SIZE]; packet.Pack(buffer, ref offset); var sessionKey = new byte[16]; var sessionSalt = new byte[16]; var sessionAuth = new byte[32]; // TODO add _txRoc logic var index = ((ulong)_txRoc << 16) + packet.SequenceNumber; GenerateSessionKey(_txKey, _txSalt, sessionKey, sessionSalt, sessionAuth); var sessionIv = new byte[BLOCK_SIZE]; var temp = new byte[BLOCK_SIZE]; for (var i = 0; i < 14; ++i) { sessionIv[i] = sessionSalt[i]; } BufferPrimitives.SetUint32(temp, 4, packet.Ssrc); for (var i = 4; i < 8; ++i) { sessionIv[i] ^= temp[i]; } BufferPrimitives.SetVarious(temp, 8, index, 6); for (var i = 8; i < 14; ++i) { sessionIv[i] ^= temp[i]; } var keyStream = new byte[packet.Payload.Length]; var payloadOffset = offset - packet.Payload.Length; GenerateKeyStream(sessionKey, sessionIv, keyStream); for (var i = 0; i < packet.Payload.Length; ++i) { buffer[payloadOffset + i] = (byte)(packet.Payload[i] ^ keyStream[i]); } var hmac = new byte[HMAC_SHA1_SIZE]; BufferPrimitives.SetVarious(buffer, offset, _txRoc, 4); CalcHmac(sessionAuth, 20, buffer, offset + 4, hmac); BufferPrimitives.SetBytes(buffer, ref offset, hmac, 0, 10); return(BufferPrimitives.GetBytes(buffer, 0, offset)); }
public RtpPacket.ResultCodes TryParseSrtpPacket(byte[] data, out RtpPacket packet) { var result = RtpPacket.TryParse(data, out packet); if (result != RtpPacket.ResultCodes.Ok) { return(result); } var packetSize = data.Length - AUTH_TAG_SIZE; var payloadLength = packet.Payload.Length - AUTH_TAG_SIZE; var sessionKey = new byte[16]; var sessionSalt = new byte[16]; var sessionAuth = new byte[32]; // TODO add _rxRoc logic var index = ((ulong)_rxRoc << 16) + packet.SequenceNumber; GenerateSessionKey(_rxKey, _rxSalt, sessionKey, sessionSalt, sessionAuth); var hmacData = new byte[packetSize + 4]; var hmac = new byte[HMAC_SHA1_SIZE]; Array.Copy(data, 0, hmacData, 0, packetSize); BufferPrimitives.SetVarious(hmacData, packetSize, _rxRoc, 4); CalcHmac(sessionAuth, 20, hmacData, packetSize + 4, hmac); for (var i = 0; i < AUTH_TAG_SIZE; ++i) { if (data[packetSize + i] != hmac[i]) { return(RtpPacket.ResultCodes.IncorrectSign); } } var sessionIv = new byte[BLOCK_SIZE]; var temp = new byte[BLOCK_SIZE]; for (var i = 0; i < 14; ++i) { sessionIv[i] = sessionSalt[i]; } BufferPrimitives.SetUint32(temp, 4, packet.Ssrc); for (var i = 4; i < 8; ++i) { sessionIv[i] ^= temp[i]; } BufferPrimitives.SetVarious(temp, 8, index, 6); for (var i = 8; i < 14; ++i) { sessionIv[i] ^= temp[i]; } var keyStream = new byte[payloadLength]; var payload = new byte[payloadLength]; GenerateKeyStream(sessionKey, sessionIv, keyStream); for (var i = 0; i < payloadLength; ++i) { payload[i] = (byte)(packet.Payload[i] ^ keyStream[i]); } packet.Payload = payload; return(RtpPacket.ResultCodes.Ok); }