public int Transform(Buffer buffer, int length) { Log.Trace("BlockCipher.Transform: input length {0}", length); using (var encryptor = encryptionAlgorithm.CreateEncryptor(encryptionKey, encryptionIV)) using (var ms = new MemoryStream(length + BlockSizeInBytes)) using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { #if UNITY_WORKAROUND // Workaround for ancient mono 2.0 of Unity3D // Multiple Write() calls are not properly handled there. byte[] plaintext = buffer.ToArray(); if (Log.Level <= LogLevel.Trace) { Log.Trace("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 (Log.Level <= LogLevel.Trace) { Log.Trace("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 (Log.Level <= LogLevel.Trace) { Log.Trace("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; } }