public int Transform(Buffer buffer, int length) { Trace.Log("BlockCipher.Transform: input length {0}", length); using (var encryptor = algorithm.CreateEncryptor(encryptionKey, encryptionIV)) using (var ms = new MemoryStream(length + BlockSizeInBytes)) using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { #if (UNITY_WORKAROUND && UNITY_MONO) // Workaround for ancient mono 2.0 of Unity3D // Multiple Write() calls are not properly handled there. byte[] plaintext = buffer.ToArray(); if (Config.TraceLevel <= TraceLevel.Trace) { Trace.Log("BlockCipher.Transform: input {0}", BitConverter.ToString(plaintext, plaintext.Length - length, length)); } cs.Write(plaintext, plaintext.Length - length, length); #else var buffers = new List <ArraySegment <byte> >(); buffer.ListEndingSegments(buffers, length); for (var i = 0; i < buffers.Count; ++i) { var segment = buffers[i]; if (Config.TraceLevel <= TraceLevel.Trace) { Trace.Log("BlockCipher.Transform: input block {0}", BitConverter.ToString(segment.Array, segment.Offset, segment.Count)); } cs.Write(segment.Array, segment.Offset, segment.Count); } #endif cs.FlushFinalBlock(); int result = (int)ms.Length; var streamBuffer = ms.GetBuffer(); if (Config.TraceLevel <= TraceLevel.Trace) { Trace.Log("BlockCipher.Transform: output {0} {1}", result, BitConverter.ToString(streamBuffer, 0, result)); } buffer.Rewind(); buffer.CopyFrom(streamBuffer, 0, result); // Store the last ciphertext block as a next encryption IV. System.Buffer.BlockCopy(streamBuffer, result - BlockSizeInBytes, encryptionIV, 0, BlockSizeInBytes); return(result); } }