/// <summary> /// Decrypt using XTEA algo and verify CRC /// </summary> /// <returns>true for success, false for failure</returns> internal bool DecryptSymmetric(NetBuffer buffer) { int bufLen = buffer.LengthBytes; if (bufLen % 8 != 0) { if (NetBase.CurrentContext != null && NetBase.CurrentContext.Log != null) NetBase.CurrentContext.Log.Info("Bad buffer size in DecryptSymmetricInPlace()"); return false; } //NetBase.CurrentContext.Log.Debug.Debug("Decrypting using key: " + Convert.ToBase64String(m_xtea.Key)); // decrypt for (int i = 0; i < bufLen; i += 8) m_xtea.DecryptBlock(buffer.Data, i, buffer.Data, i); int numPadBits = buffer.Data[bufLen - 1]; buffer.Data[bufLen - 1] = 0; // zap for correct crc calculation int dataBits = (bufLen * 8) - (24 + numPadBits); // include pad and crc buffer.ResetReadPointer(dataBits); ushort statedCrc = buffer.ReadUInt16(); // zap crc to be able to compare buffer.ResetWritePointer(dataBits); buffer.Write((ushort)0); ushort dataCrc = Checksum.Adler16(buffer.Data, 0, bufLen); //NetBase.CurrentContext.Log.Debug("Plain (len " + bufLen + "): " + Convert.ToBase64String(buffer.Data, 0, bufLen) + " Stated CRC: " + statedCrc + " Calc: " + realCrc); if (statedCrc != dataCrc) { if (NetBase.CurrentContext != null && NetBase.CurrentContext.Log != null) NetBase.CurrentContext.Log.Warning("CRC failure; expected " + dataCrc + " found " + statedCrc + " dropping packet!"); return false; } // clean up buffer.LengthBits = dataBits; buffer.ResetReadPointer(); return true; }
internal void Encode(NetConnection connection, NetBuffer intoBuffer) { if (m_type == NetMessageType.None) m_type = NetMessageType.User; intoBuffer.Write((byte)m_type, 3); switch(m_type) { case NetMessageType.UserFragmented: case NetMessageType.User: case NetMessageType.Acknowledge: case NetMessageType.AcknowledgeBitField: intoBuffer.Write((byte)m_sequenceChannel, 5); // encode channel intoBuffer.Write(m_sequenceNumber, 12); // encode sequence number break; } int byteLen = (m_buffer == null ? 0 : m_buffer.LengthBytes); if (m_type == NetMessageType.UserFragmented || m_type == NetMessageType.User || m_type == NetMessageType.Discovery || m_type == NetMessageType.Handshake) intoBuffer.Write(byteLen, 12); // encode length // encode payload if (byteLen > 0) intoBuffer.Write(m_buffer.Data, 0, byteLen); return; }
/// <summary> /// Append a CRC checksum and encrypt data in place using XTEA /// </summary> internal void EncryptSymmetric(NetBuffer buffer) { //string plain = Convert.ToBase64String(buffer.Data, 0, buffer.LengthBytes); int bufferLen = buffer.LengthBytes; // calculate number of pad bits int dataBits = buffer.LengthBits; int bitsNeeded = dataBits + 24; // 24 extra for crc and num-pad-bits int totalBits = bitsNeeded + (64 - (bitsNeeded % 64)); int padBits = totalBits - bitsNeeded; // write to ensure zeroes in buffer (crc and num-pad-bits space) buffer.Write((uint)0, 24); if (padBits > 0) buffer.Write((ulong)0, padBits); int writePadBitsPosition = buffer.LengthBits - 8; // write crc ushort crc = Checksum.Adler16(buffer.Data, 0, buffer.LengthBytes); buffer.ResetWritePointer(dataBits); buffer.Write(crc); // write num-pad-bits in LAST byte buffer.ResetWritePointer(writePadBitsPosition); buffer.Write((byte)padBits); // encrypt in place int ptr = 0; bufferLen = buffer.LengthBytes; while (ptr < bufferLen) { m_xtea.EncryptBlock(buffer.Data, ptr, buffer.Data, ptr); ptr += 8; } return; }