2005-01-10 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / corlib / Test / System.Security.Cryptography / CryptoStreamTest.cs
1 //
2 // CryptoStreamTest.cs - NUnit Test Cases for CryptoStream
3 //
4 // Author:
5 //      Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 /* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
31  * 
32  * DO NOT USE ANY OF THE TEST CASE AS SAMPLES FOR YOUR OWN CODE. MANY
33  * CASES CONTAINS ERRORS AND AREN'T SECURE IN THEIR USE.
34  * 
35  * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING */
36
37 using NUnit.Framework;
38 using System;
39 using System.IO;
40 using System.Reflection;
41 using System.Runtime.InteropServices;
42 using System.Security.Cryptography;
43 using System.Text;
44
45 namespace MonoTests.System.Security.Cryptography {
46
47         // much useful for debugging
48         public class DebugStream : MemoryStream {
49
50                 // constructor
51
52                 public DebugStream () : base () {}
53                 public DebugStream (byte[] buffer) : base (buffer) {}
54                 public DebugStream (int capacity) : base (capacity) {}
55
56                 public override bool CanRead {
57                         get { return base.CanRead; }
58                 }
59
60                 public override bool CanSeek {
61                         get { return base.CanSeek; }
62                 }
63
64                 public override bool CanWrite {
65                         get { return base.CanWrite; }
66                 }
67
68                 public override int Capacity {
69                         get { return base.Capacity; }
70                         set { base.Capacity = value; }
71                 }
72
73                 public override long Length {
74                         get { return base.Length; }
75                 }
76                 
77                 public override long Position {
78                         get { return base.Position; }
79                         set { base.Position = value; }
80                 }
81
82                 // methods
83                 
84                 public override void Close () 
85                 {
86                         base.Close ();
87                 }
88                 
89                 public override void Flush () 
90                 {
91                         base.Flush ();
92                 }
93
94                 public override byte[] GetBuffer () 
95                 {
96                         return base.GetBuffer ();
97                 }
98
99                 public override int Read ([In,Out] byte[] buffer, int offset, int count)
100                 {
101                         int len = base.Read (buffer, offset, count);
102                         return len;
103                 }
104
105                 public override int ReadByte () 
106                 {
107                         return base.ReadByte ();
108                 }
109
110                 public override long Seek (long offset, SeekOrigin loc)
111                 {
112                         return base.Seek (offset, loc);
113                 }
114                 
115                 public override void SetLength (long value)
116                 {
117                         base.SetLength (value);
118                 }
119                 
120                 public override byte[] ToArray () 
121                 {
122                         return base.ToArray ();
123                 }
124
125                 public override void Write (byte[] buffer, int offset, int count) 
126                 {
127                         base.Write (buffer, offset, count);
128                 }
129
130                 public override void WriteByte (byte value) 
131                 {
132                         base.WriteByte (value);
133                 }
134
135                 public override void WriteTo (Stream stream) 
136                 {
137                         base.WriteTo (stream);
138                 }
139         }
140
141         [TestFixture]
142         public class CryptoStreamTest : Assertion {
143
144                 Stream readStream;
145                 Stream writeStream;
146                 ICryptoTransform encryptor;
147                 ICryptoTransform decryptor;
148                 CryptoStream cs;
149                 SymmetricAlgorithm aes;
150
151                 [SetUp]
152                 public void SetUp () 
153                 {
154                         if (readStream == null) {
155                                 readStream = new FileStream ("read", FileMode.OpenOrCreate, FileAccess.Read);
156                                 writeStream = new FileStream ("write", FileMode.OpenOrCreate, FileAccess.Write);
157                                 aes = SymmetricAlgorithm.Create ();
158                                 encryptor = aes.CreateEncryptor ();
159                                 decryptor = aes.CreateEncryptor ();
160                         }
161                 }
162
163                 [TearDown]
164                 public void TearDown () 
165                 {
166                         try {
167                                 if (File.Exists ("read"))
168                                         File.Delete ("read");
169                                 if (File.Exists ("write"))
170                                         File.Delete ("write");
171                                 if (File.Exists ("*.tmp"))\r
172                                         File.Delete ("*.tmp");\r
173                         }
174                         catch {}
175                 }
176
177                 public void AssertEquals (string msg, byte[] array1, byte[] array2)
178                 {
179                         AllTests.AssertEquals (msg, array1, array2);
180                 }
181
182                 [Test]
183                 [ExpectedException (typeof (NullReferenceException))]
184                 public void StreamNull ()
185                 {
186                         cs = new CryptoStream (null, encryptor, CryptoStreamMode.Read);
187                 }
188
189                 [Test]
190                 [ExpectedException (typeof (NullReferenceException))]
191                 public void TransformNull ()
192                 {
193                         MemoryStream write = new MemoryStream (8);
194                         byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
195                         cs = new CryptoStream (write, null, CryptoStreamMode.Write);
196                         cs.Write (data, 0, 8);
197                 }
198
199                 [Test]
200                 public void StreamReadModeRead () 
201                 {
202                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
203                         Assert ("Read.CanRead", cs.CanRead);
204                         Assert ("Read.CanWrite", !cs.CanWrite);
205                         Assert ("Read.CanSeek", !cs.CanSeek);
206                 }
207
208                 [Test]
209                 [ExpectedException (typeof (ArgumentException))]
210                 public void StreamReadModeWrite () 
211                 {
212                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Write);
213                 }
214
215                 [Test]
216                 [ExpectedException (typeof (ArgumentException))]
217                 public void StreamWriteModeRead () 
218                 {
219                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Read);
220                 }
221
222                 [Test]
223                 public void StreamWriteModeWrite () 
224                 {
225                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
226                         Assert ("Read.CanRead", !cs.CanRead);
227                         Assert ("Read.CanWrite", cs.CanWrite);
228                         Assert ("Read.CanSeek", !cs.CanSeek);
229                 }
230
231                 [Test]
232                 [ExpectedException (typeof (NotSupportedException))]
233                 public void GetLength () 
234                 {\r
235                         DebugStream debug = new DebugStream ();\r
236                         cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
237                         long x = cs.Length;
238                 }
239
240                 [Test]
241                 [ExpectedException (typeof (NotSupportedException))]
242                 public void GetPosition () 
243                 {\r
244                         DebugStream debug = new DebugStream ();\r
245                         cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
246                         long x = cs.Position;
247                 }
248
249                 [Test]\r
250                 [ExpectedException (typeof (NotSupportedException))]\r
251                 public void SetPosition () 
252                 {\r
253                         DebugStream debug = new DebugStream ();\r
254                         cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
255                         cs.Position = 1;
256                 }
257
258                 [Test]\r
259                 [ExpectedException (typeof (NotSupportedException))]\r
260                 public void Seek () 
261                 {\r
262                         DebugStream debug = new DebugStream ();\r
263                         cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
264                         cs.Seek (0, SeekOrigin.Begin);
265                 }
266
267                 [Test]\r
268                 [ExpectedException (typeof (NotSupportedException))]\r
269                 public void SetLength () 
270                 {\r
271                         DebugStream debug = new DebugStream ();\r
272                         cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
273                         cs.SetLength (0);
274                 }
275
276                 [Test]
277                 // LAMESPEC : [ExpectedException (typeof (NotSupportedException))]
278                 public void FlushReadStream () 
279                 {
280                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
281                         cs.Flush ();
282                 }
283
284                 [Test]
285                 [ExpectedException (typeof (NotSupportedException))]
286                 public void FlushFinalBlockReadStream () 
287                 {
288                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
289                         cs.FlushFinalBlock ();
290                 }
291
292                 [Test]
293                 [ExpectedException (typeof (NotSupportedException))]
294                 public void FlushFinalBlock_Dual () 
295                 {
296                         // do no corrupt writeStream in further tests\r
297                         using (FileStream fs = new FileStream ("FlushFinalBlock_Dual.tmp", FileMode.OpenOrCreate, FileAccess.Write)) {\r
298                                 byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
299                                 cs = new CryptoStream (fs, encryptor, CryptoStreamMode.Write);
300                                 cs.Write (data, 0, data.Length);
301                                 cs.FlushFinalBlock ();
302                                 cs.FlushFinalBlock ();
303                         }
304                 }
305
306                 [Test]\r
307                 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
308                 [ExpectedException (typeof (ArgumentNullException))]
309                 public void FlushFinalBlock_Disposed () 
310                 {\r
311                         // do no corrupt writeStream in further tests\r
312                         using (FileStream fs = new FileStream ("FlushFinalBlock_Disposed.tmp", FileMode.OpenOrCreate, FileAccess.Write)) {\r
313                                 cs = new CryptoStream (fs, encryptor, CryptoStreamMode.Write);
314                                 cs.Clear ();
315                                 cs.FlushFinalBlock ();
316                         }
317                 }
318
319                 [Test]
320                 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
321                 [ExpectedException (typeof (ArgumentNullException))]
322                 public void Read_Disposed () 
323                 {\r
324                         // do no corrupt readStream in further tests\r
325                         using (FileStream fs = new FileStream ("read", FileMode.OpenOrCreate, FileAccess.Read)) {\r
326                                 byte[] buffer = new byte [8];
327                                 cs = new CryptoStream (fs, encryptor, CryptoStreamMode.Read);
328                                 cs.Clear ();
329                                 cs.Read (buffer, 0, 8);
330                         }
331                 }
332
333                 [Test]
334                 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
335 #if NET_2_0
336                 [ExpectedException (typeof (IndexOutOfRangeException))]
337 #else
338                 [Category ("NotDotNet")] // Test cause System.ExecutionEngineException on MS runtime
339 #endif
340                 public void Read_Disposed_Break () 
341                 {\r
342                         // do no corrupt readStream in further tests\r
343                         using (FileStream fs = new FileStream ("read", FileMode.OpenOrCreate, FileAccess.Read)) {\r
344                                 byte[] buffer = new byte [8];
345                                 cs = new CryptoStream (fs, encryptor, CryptoStreamMode.Read);
346                                 int len = cs.Read (buffer, 0, 4);
347                                 AssertEquals ("Read 4", 4, len);
348                                 cs.Clear ();
349                                 len = cs.Read (buffer, 3, 4);
350                         }
351                 }
352
353                 [Test]\r
354                 [ExpectedException (typeof (NotSupportedException))]\r
355                 public void Read_WriteStream () 
356                 {
357                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
358                         byte[] buffer = new byte [8];
359                         cs.Read (buffer, 0, 8);
360                 }
361
362                 [Test]\r
363                 [ExpectedException (typeof (NullReferenceException))]
364                 public void Read_NullBuffer () 
365                 {
366                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
367                         cs.Read (null, 0, 8);
368                 }
369
370                 [Test]\r
371                 public void Read_EmptyBuffer_ZeroCount () 
372                 {
373                         byte[] buffer = new byte [0];
374                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
375                         int len = cs.Read (buffer, 0, 0);
376                         AssertEquals ("Read 0", 0, len);
377                 }
378
379                 [Test]
380                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
381                 public void Read_NegativeOffset () 
382                 {
383                         byte[] buffer = new byte [8];
384                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
385                         cs.Read (buffer, -1, 8);
386                 }
387
388                 [Test]\r
389                 public void Read_ZeroCount () 
390                 {
391                         byte[] buffer = new byte [8];
392                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
393                         int len = cs.Read (buffer, 0, 0);
394                         AssertEquals ("Read 0", 0, len);
395                 }
396
397                 [Test]
398                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
399                 public void Read_NegativeCount () 
400                 {
401                         byte[] buffer = new byte [8];
402                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
403                         cs.Read (buffer, 0, -1);
404                 }
405
406                 [Test]
407                 [ExpectedException (typeof (ArgumentException))]
408                 public void Read_OverflowCount () 
409                 {
410                         byte[] buffer = new byte [8];
411                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
412                         cs.Read (buffer, 0, Int32.MaxValue);
413                 }
414
415                 [Test]
416                 [ExpectedException (typeof (ArgumentException))]
417                 public void Read_InvalidOffset () 
418                 {
419                         byte[] buffer = new byte [8];
420                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
421                         cs.Read (buffer, 5, 4);
422                 }
423
424                 [Test]
425                 [ExpectedException (typeof (ArgumentException))]
426                 public void Read_OverflowOffset () 
427                 {
428                         byte[] buffer = new byte [8];
429                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
430                         cs.Read (buffer, Int32.MaxValue, 4);
431                 }
432
433                 [Test]
434                 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
435 #if NET_2_0
436                 [ExpectedException (typeof (IndexOutOfRangeException))]
437 #else
438                 [Category ("NotDotNet")] // Test cause System.ExecutionEngineException on MS runtime
439 #endif
440                 public void Write_Disposed () 
441                 {\r
442                         // do no corrupt writeStream in further tests\r
443                         using (FileStream fs = new FileStream ("Write_Disposed.tmp", FileMode.OpenOrCreate, FileAccess.Write)) {\r
444                                 byte[] buffer = new byte [8];
445                                 cs = new CryptoStream (fs, encryptor, CryptoStreamMode.Write);
446                                 cs.Clear ();
447                                 cs.Write (buffer, 0, 8);
448                         }
449                 }
450
451                 [Test]\r
452                 [ExpectedException (typeof (NotSupportedException))]\r
453                 public void Write_ReadStream () 
454                 {
455                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
456                         byte[] buffer = new byte [8];
457                         cs.Write (buffer, 0, 8);
458                 }
459
460                 [Test]
461                 [ExpectedException (typeof (NullReferenceException))]
462                 public void Write_NullBuffer () 
463                 {
464                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
465                         cs.Write (null, 0, 8);
466                 }
467
468                 [Test]\r
469                 public void Write_EmptyBuffer_ZeroCount () 
470                 {
471                         byte[] buffer = new byte [0];
472                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
473                         cs.Write (buffer, 0, 0);
474                 }
475
476                 [Test]
477                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
478                 public void Write_NegativeOffset () 
479                 {
480                         byte[] buffer = new byte [8];
481                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
482                         cs.Write (buffer, -1, 8);
483                 }
484
485                 [Test]
486                 [ExpectedException (typeof (ArgumentException))]
487                 public void Write_OverflowOffset () 
488                 {
489                         byte[] buffer = new byte [8];
490                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
491                         cs.Write (buffer, Int32.MaxValue, 8);
492                 }
493
494                 [Test]
495                 public void Write_ZeroCount () 
496                 {
497                         byte[] buffer = new byte [8];
498                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
499                         cs.Write (buffer, 0, 0);
500                 }
501
502                 [Test]
503                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
504                 public void Write_NegativeCount () 
505                 {
506                         byte[] buffer = new byte [8];
507                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
508                         cs.Write (buffer, 0, -1);
509                 }
510
511                 [Test]
512                 [ExpectedException (typeof (ArgumentException))]
513                 public void Write_InvalidOffset () 
514                 {\r
515                         DebugStream debug = new DebugStream ();\r
516                         byte[] buffer = new byte [8];
517                         cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
518                         cs.Write (buffer, 5, 4);
519                 }
520
521                 [Test]
522                 [ExpectedException (typeof (ArgumentException))]
523                 public void Write_OverflowCount () 
524                 {\r
525                         DebugStream debug = new DebugStream ();\r
526                         byte[] buffer = new byte [8];
527                         cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
528                         cs.Write (buffer, 0, Int32.MaxValue);
529                 }
530
531                 [Test]
532                 public void FullRoundtripRead () 
533                 {
534                         byte[] encrypted;
535                         using (DebugStream mem1 = new DebugStream ()) {
536                                 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
537                                 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
538                                         crypt.Write (toEncrypt, 0, toEncrypt.Length);
539                                         crypt.FlushFinalBlock ();
540                                 }
541                                 encrypted = mem1.ToArray ();
542                         }
543                                         
544                         using (DebugStream mem2 = new DebugStream (encrypted)) {
545                                 byte[] buffer = new byte [1024];
546                                 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
547                                 int len = cr.Read (buffer, 0, buffer.Length);
548                                 cr.Close ();
549                                 AssertEquals ("Full Length Read", 34, len);
550                                 AssertEquals ("Full Block Read", "Please encode me!", Encoding.Unicode.GetString (buffer, 0, len));
551                         }
552                 }
553
554                 // bugzilla 46143 (adapted from test case by Joerg Rosenkranz)
555                 [Test]
556                 public void PartialRoundtripRead () 
557                 {
558                         byte[] encrypted;
559                         using (DebugStream mem1 = new DebugStream ()) {
560                                 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
561                                 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
562                                         crypt.Write (toEncrypt, 0, toEncrypt.Length);
563                                         crypt.FlushFinalBlock ();
564                                 }
565                                 encrypted = mem1.ToArray ();
566                         }
567                                         
568                         using (DebugStream mem2 = new DebugStream (encrypted)) {
569                                 byte[] buffer = new byte [1024];
570                                 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
571                                 int len = cr.Read (buffer, 0, 20);
572                                 cr.Clear ();
573                                 cr.Close ();
574                                 AssertEquals ("Partial Length Read", 20, len);
575                                 AssertEquals ("Partial Block Read", "Please enc", Encoding.Unicode.GetString (buffer, 0, len));
576                         }
577                 }
578
579                 // bugzilla: 40689 (adapted from test case by Henning Westerholt)
580                 [Test]
581                 public void WriteOnBlockWithFinal () 
582                 {
583                         byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
584                         byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
585                         DES des = DES.Create ();
586
587                         MemoryStream msin = new MemoryStream ();
588                         CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
589                         byte[] data = new byte [2200];
590                         enc.Write (data, 0, 2200);
591                         enc.FlushFinalBlock ();
592                         msin.Position = 0;
593                         AssertEquals ("Encryped Write Length", 2208, msin.Length); // 2200 + padding
594
595                         MemoryStream msout = new MemoryStream ();
596                         msout.SetLength (0);
597
598                         byte[] tmp = new byte [1024];
599                         long readlen = 0;
600                         long totallen = msin.Length;
601
602                         CryptoStream dec = new CryptoStream (msout, des.CreateDecryptor (desKey, desIV), CryptoStreamMode.Write);
603                         int len = msin.Read (tmp, 0, 1024);
604                         while (len > 0) {
605                                 dec.Write (tmp, 0, len);
606                                 readlen += len;
607                                 len = msin.Read (tmp, 0, 1024);
608                         }
609                         AssertEquals ("Decryped Write Length", 2200, msout.Length);
610
611                         dec.Close ();
612                         dec.Clear ();
613                         msout.Close ();
614                         msin.Close ();
615
616                         AssertEquals ("Read Length", 2208, readlen); // 2200 + padding
617                 }
618
619                 [Test]
620                 public void PreGeneratedStreams ()
621                 {
622                         byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
623                         byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
624                         DES des = DES.Create ();
625         
626                         for (int i=0; i < 9; i++) {
627                                 MemoryStream msin = new MemoryStream ();
628                                 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
629                                 byte[] data = new byte [i];
630                                 enc.Write (data, 0, i);
631                                 enc.FlushFinalBlock ();
632
633                                 string msg = "PreGeneratedStream #" + i;
634                                 string result = BitConverter.ToString (msin.ToArray ());
635                                 switch (i) {
636                                         case 0:
637                                                 AssertEquals (msg, "92-C9-DB-45-30-0B-93-2F", result); 
638                                                 break;
639                                         case 1:
640                                                 AssertEquals (msg, "08-CF-A1-37-BD-56-D0-65", result); 
641                                                 break;
642                                         case 2:
643                                                 AssertEquals (msg, "58-87-D4-9B-2C-27-97-0C", result); 
644                                                 break;
645                                         case 3:
646                                                 AssertEquals (msg, "07-35-90-94-68-7D-51-FB", result); 
647                                                 break;
648                                         case 4:
649                                                 AssertEquals (msg, "BF-00-98-C5-20-71-D0-DB", result); 
650                                                 break;
651                                         case 5:
652                                                 AssertEquals (msg, "1A-55-C8-6E-C1-9B-31-82", result); 
653                                                 break;
654                                         case 6:
655                                                 AssertEquals (msg, "2D-2B-76-41-61-0E-00-0C", result); 
656                                                 break;
657                                         case 7:
658                                                 AssertEquals (msg, "DC-FF-73-D2-7F-D7-48-5D", result); 
659                                                 break;
660                                         case 8:
661                                                 AssertEquals (msg, "E1-B2-46-E5-A7-C7-4C-BC-0E-40-4A-FC-08-92-B1-EB", result); 
662                                                 break;
663                                 }
664                         }
665                 }
666
667                 private byte[] EmptyStream (PaddingMode mode) 
668                 {
669                         SymmetricAlgorithm algo = Rijndael.Create ();
670                         algo.Key = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
671                         algo.IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
672                         algo.Padding = mode;
673                         MemoryStream ms = new MemoryStream ();
674                         CryptoStream cs = new CryptoStream (ms, algo.CreateEncryptor(), CryptoStreamMode.Write);
675                         cs.Write (ms.GetBuffer (), 0, (int) ms.Length);
676                         cs.FlushFinalBlock ();
677                         cs.Flush ();
678                         return ms.ToArray ();
679                 }
680
681                 [Test]
682                 public void EmptyStreamWithPaddingNone () 
683                 {
684                         byte[] result = EmptyStream (PaddingMode.None);
685                         AssertEquals ("Result Length", 0, result.Length);
686                 }
687
688                 [Test]
689                 public void EmptyStreamWithPaddingPKCS7 () 
690                 {
691                         byte[] expected = { 0x07, 0xFE, 0xEF, 0x74, 0xE1, 0xD5, 0x03, 0x6E, 0x90, 0x0E, 0xEE, 0x11, 0x8E, 0x94, 0x92, 0x93 };
692                         byte[] result = EmptyStream (PaddingMode.PKCS7);
693                         AssertEquals ("Result Length", 16, result.Length);
694                         AssertEquals ("Result", expected, result);
695                 }
696
697                 [Test]
698                 public void EmptyStreamWithPaddingZeros () 
699                 {
700                         byte[] result = EmptyStream (PaddingMode.Zeros);
701                         AssertEquals ("Result Length", 0, result.Length);
702                 }
703
704                 // bugzilla: 49323 (adapted from test case by Carlos Guzmán Álvarez)
705                 [Test]
706                 public void MultiblocksWithPartial () 
707                 {
708                         SymmetricAlgorithm tdes = new TripleDESCryptoServiceProvider ();
709                         tdes.Key = new byte[] {161, 54, 179, 213, 89, 75, 130, 4, 186, 99, 158, 127, 19, 195, 175, 143, 79, 109, 25, 202, 237, 235, 62, 170};
710                         tdes.IV = new byte[] {193, 227, 54, 132, 68, 172, 55, 91};
711
712                         byte[] fragment = new byte[] {20, 0, 0, 12, 181, 134, 8, 230, 185, 75, 19, 129, 101, 142, 118, 190};
713                         byte[] mac = new byte[] {42, 148, 229, 58, 185, 249, 154, 131, 157, 79, 176, 168, 143, 71, 0, 118, 5, 10, 95, 8};
714                                                                                                                                                                                                   
715                         // Encryption ( fragment + mac [+ padding + padding_length] )
716                         MemoryStream ms = new MemoryStream ();
717                         CryptoStream cs = new CryptoStream (ms, tdes.CreateEncryptor (), CryptoStreamMode.Write);
718                         cs.Write (fragment, 0, fragment.Length);
719                         cs.Write (mac, 0, mac.Length);
720                         // Calculate padding_length
721                         int fragmentLength = fragment.Length + mac.Length + 1;
722                         int padding = (((fragmentLength / 8) * 8) + 8) - fragmentLength;
723                         // Write padding length byte
724                         cs.WriteByte ((byte)padding);
725                         cs.Close ();
726                         byte[] encrypted = ms.ToArray ();
727                         byte[] expected = new byte[] { 0x9c, 0x99, 0x56, 0x8e, 0x75, 0x3e, 0x02, 0x95, 0x5b, 0x5c, 0x46, 0x8b, 0xcf, 0xf8, 0x27, 0x21, 0x53, 0x5f, 0x3d, 0xd8, 0x16, 0x95, 0x82, 0x3d, 0x88, 0x9b, 0x9a, 0x47, 0xda, 0x97, 0x90, 0x86, 0x50, 0x0e, 0x48, 0xee, 0xe7, 0x9b, 0x25, 0x41 };
728                         AssertEquals ("MultiblocksWithPartial", expected, encrypted);
729                 }
730
731                 // Adapted from Subba Rao Thirumoorthy email on mono-devel-list (december 2003)
732                 private byte[] NonMultipleOfBlockSize_Encrypt (ICryptoTransform ct, byte[] data)
733                 {
734                         DebugStream stream = new DebugStream ();
735                         CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Write);
736
737                         int len = 0;
738                         long myLength = 0;
739                         byte[] Buffer = new byte [1024];
740                         
741                         DebugStream fout = new DebugStream (data);
742                         while (myLength < data.Length) {
743                                 len = fout.Read (Buffer, 0, 1023);
744                                 if (len == 0)
745                                         break;
746                                 CryptStream.Write (Buffer, 0, len);
747                                 CryptStream.Flush ();
748                                 myLength = myLength + len;
749                         }
750                         CryptStream.FlushFinalBlock ();
751                         // we must ensure that the result is correct
752                         AssertEquals ("Length(final)", 64, len);
753                         byte[] result = stream.ToArray ();
754                         string end = BitConverter.ToString (result, 65520, 16);
755                         AssertEquals ("End part", "04-70-19-1D-28-C5-BD-9A-23-C6-60-E2-28-96-38-65", end);
756
757                         CryptStream.Close();
758                         stream.Close();
759                         return result;
760                 }
761
762                 private byte[] NonMultipleOfBlockSize_Decrypt (ICryptoTransform ct, byte[] data) 
763                 {
764                         DebugStream stream = new DebugStream (data);
765                         CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Read);
766
767                         int len = 0;
768                         long myLength = 0;
769                         byte[] Buffer = new Byte [1024];
770
771                         DebugStream fout = new DebugStream ();
772                         // each returned block must be 1023 bytes long 
773                         // even if this isn't a multiple of the block size
774                         while ((len = CryptStream.Read (Buffer, 0, 1023)) != 0) {
775                                 fout.Write (Buffer, 0, len);
776                                 fout.Flush ();
777                                 myLength = myLength + len;
778                         }
779
780                         byte[] result = fout.ToArray ();
781                         CryptStream.Close ();
782                         stream.Close ();
783                         return result;
784                 }
785
786                 [Test]
787                 public void NonMultipleOfBlockSize ()
788                 {
789                         byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
790                         byte[] iv  = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
791                         byte[] data = new byte [65536];
792
793                         RijndaelManaged aes = new RijndaelManaged ();
794                         ICryptoTransform encryptor = aes.CreateEncryptor (key, iv);
795                         byte[] encdata = NonMultipleOfBlockSize_Encrypt (encryptor, data);
796                         AssertEquals ("Encrypted Data Length", (data.Length + (aes.BlockSize >> 3)), encdata.Length);
797                         
798                         ICryptoTransform decryptor = aes.CreateDecryptor (key, iv);
799                         byte[] decdata = NonMultipleOfBlockSize_Decrypt (decryptor, encdata);
800                         AssertEquals ("Decrypted Data Length", data.Length, decdata.Length);
801
802                         int i = 0;
803                         bool b = true;
804                         while (b && (i < data.Length)) {
805                                 b = (data [i] == decdata [i]);
806                                 i++;
807                         }
808                         Assert ("NonMultipleOfBlockSize", b);
809                 }
810
811                 // bugzilla: 51322 - indirectly related but it explains why my first (unapplied) patch didn't work
812                 [Test]
813                 public void DecryptPartial_TransformFinalBlock_required () 
814                 {
815                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
816                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
817                         DES des = DES.Create ();
818
819                         byte[] data = Encoding.Unicode.GetBytes ("ximian");     // 12 bytes, 1.5 DES block size
820                         DebugStream encrypted = new DebugStream ();
821                         cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
822                         cs.Write (data, 0, data.Length);
823                         cs.Close ();
824
825                         data = encrypted.ToArray ();
826                         DebugStream decrypted = new DebugStream (data);
827                         cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
828                         int len = cs.Read (data, 0, data.Length);
829                         cs.Close ();
830                         AssertEquals ("Length", 12, len);
831                         AssertEquals ("Unicode DES Roundtrip", "ximian", Encoding.Unicode.GetString (data, 0, len));
832                 }
833
834                 [Test]
835                 public void DecryptPartial_TransformFinalBlock_2Pass () 
836                 {
837                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
838                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
839                         DES des = DES.Create ();
840
841                         byte[] data = Encoding.Unicode.GetBytes ("ximian");     // 12 bytes, 1.5 DES block size
842                         DebugStream encrypted = new DebugStream ();
843                         cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
844                         cs.Write (data, 0, data.Length);
845                         cs.Close ();
846
847                         data = encrypted.ToArray ();
848                         DebugStream decrypted = new DebugStream (data);
849                         cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
850                         int len = cs.Read (data, 0, 6);
851                         AssertEquals ("Length (1st pass)", 6, len);
852                         AssertEquals ("Partial DES Roundtrip", "xim", Encoding.Unicode.GetString (data, 0, len));
853                         len += cs.Read (data, 6, 8);
854                         AssertEquals ("Length (1st+2nd)", 12, len);
855                         AssertEquals ("Full DES Roundtrip", "ximian", Encoding.Unicode.GetString (data, 0, len));
856                         cs.Close ();
857                 }
858
859                 // based on http://www.c-sharpcorner.com/Code/2002/May/FileEncryption.asp
860                 [Test]
861                 public void WriteByteReadByte () 
862                 {
863                         DebugStream original = new DebugStream (Encoding.Unicode.GetBytes ("ximian"));
864
865                         DebugStream encrypted = new DebugStream ();
866                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
867                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
868                         DES des = DES.Create ();
869                         cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
870
871                         int data;
872                         while ((data = original.ReadByte ()) != -1)
873                                 cs.WriteByte((byte) data);
874                         cs.Close ();
875
876                         byte[] result = encrypted.ToArray ();
877                         AssertEquals ("Encrypted", "18-EA-93-3F-20-86-D2-AA-78-02-D7-6F-E4-47-17-9C", BitConverter.ToString (result));
878
879                         encrypted = new DebugStream (result);
880                         DebugStream decrypted = new DebugStream ();
881                         cs = new CryptoStream (encrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
882
883                         while ((data = cs.ReadByte ()) != -1)
884                                 decrypted.WriteByte((byte) data);
885                         cs.Close ();
886                         decrypted.Close ();
887
888                         AssertEquals ("W/R Byte Roundtrip", "ximian", Encoding.Unicode.GetString (decrypted.ToArray ()));
889                 }
890
891                 // based http://www.4guysfromrolla.com/webtech/090501-1.shtml
892
893                 public string EncryptData (ICryptoTransform des, string strData) 
894                 {
895                         strData = String.Format("{0,5:00000}" + strData, strData.Length);
896                         byte[] data = Encoding.ASCII.GetBytes (strData);
897
898                         MemoryStream mStream = new MemoryStream (data); 
899                         CryptoStream cs = new CryptoStream (mStream, des, CryptoStreamMode.Read);        
900                         MemoryStream mOut = new MemoryStream ();
901         
902                         int bytesRead; 
903                         byte[] output = new byte [1024]; 
904                         do { 
905                                 bytesRead = cs.Read (output, 0, 1024);
906                                 if (bytesRead != 0) 
907                                         mOut.Write (output, 0, bytesRead); 
908                         } 
909                         while (bytesRead > 0); 
910         
911                         return Convert.ToBase64String (mOut.ToArray ());
912                 }
913
914                 public string DecryptData (ICryptoTransform des, string strData) 
915                 {
916                         MemoryStream mOut = new MemoryStream ();
917                         byte[] data = Convert.FromBase64String (strData);
918                         CryptoStream cs = new CryptoStream (mOut, des, CryptoStreamMode.Write);        
919                         cs.Write (data, 0, (int)data.Length);
920                         cs.FlushFinalBlock ();
921                         return Encoding.ASCII.GetString (mOut.ToArray ()).Substring (5);
922                 }
923
924                 [Test]
925                 public void EncryptOnRead () 
926                 {
927                         SHA1 sha = SHA1.Create ();
928                         byte[] vector = sha.ComputeHash (Encoding.ASCII.GetBytes ("s3kr3t"));
929                         byte[] key = new byte [8];
930                         Buffer.BlockCopy (vector, 0, key, 0, key.Length);
931                         byte[] iv = new byte [8];
932                         Buffer.BlockCopy (vector, 8, iv, 0, iv.Length);
933
934                         DES des = DES.Create ();
935
936                         StringBuilder sb = new StringBuilder ();
937                         sb.Append ("a");
938                         string data = sb.ToString ();
939                         string encdata = EncryptData (des.CreateEncryptor (key, iv), data);
940                         string decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
941                         AssertEquals ("Encrypt-" + data, "9YVfvrh5yj0=", encdata);
942                         AssertEquals ("Decrypt-" + data, data, decdata);
943
944                         sb.Append ("a");
945                         data = sb.ToString ();
946                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
947                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
948                         AssertEquals ("Encrypt-" + data, "qNe4d0UlkU8=", encdata);
949                         AssertEquals ("Decrypt-" + data, data, decdata);
950
951                         sb.Append ("a");
952                         data = sb.ToString ();
953                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
954                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
955                         AssertEquals ("Encrypt-" + data, "OcernYAQ1NAME/Gny+ZuaA==", encdata);
956                         AssertEquals ("Decrypt-" + data, data, decdata);
957
958                         sb.Append ("a");
959                         data = sb.ToString ();
960                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
961                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
962                         AssertEquals ("Encrypt-" + data, "H5UveR2lds1T+IWN4pks2Q==", encdata);
963                         AssertEquals ("Decrypt-" + data, data, decdata);
964
965                         sb.Append ("a");
966                         data = sb.ToString ();
967                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
968                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
969                         AssertEquals ("Encrypt-" + data, "dDQ3HAVtTbiRwwUqWANaeA==", encdata);
970                         AssertEquals ("Decrypt-" + data, data, decdata);
971
972                         sb.Append ("a");
973                         data = sb.ToString ();
974                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
975                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
976                         AssertEquals ("Encrypt-" + data, "At1r7dVDjJlQidf4QzCNkw==", encdata);
977                         AssertEquals ("Decrypt-" + data, data, decdata);
978
979                         sb.Append ("a");
980                         data = sb.ToString ();
981                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
982                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
983                         AssertEquals ("Encrypt-" + data, "DFDJWJGaNrFVBDXovsq1ew==", encdata);
984                         AssertEquals ("Decrypt-" + data, data, decdata);
985
986                         sb.Append ("a");
987                         data = sb.ToString ();
988                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
989                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
990                         AssertEquals ("Encrypt-" + data, "gM040QGMPOBj3u1lEK4XHQ==", encdata);
991                         AssertEquals ("Decrypt-" + data, data, decdata);
992
993                         sb.Append ("a");
994                         data = sb.ToString ();
995                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
996                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
997                         AssertEquals ("Encrypt-" + data, "P5hRUhrxOWFX0ER/IjJL/Q==", encdata);
998                         AssertEquals ("Decrypt-" + data, data, decdata);
999
1000                         sb.Append ("a");
1001                         data = sb.ToString ();
1002                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1003                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1004                         AssertEquals ("Encrypt-" + data, "uDIaQ1uXtWUIboGFLt306Q==", encdata);
1005                         AssertEquals ("Decrypt-" + data, data, decdata);
1006
1007                         sb.Append ("a");
1008                         data = sb.ToString ();
1009                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1010                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1011                         AssertEquals ("Encrypt-" + data, "giJKTXfad5Z8hebhXtYZ4hmKX/EC8w6x", encdata);
1012                         AssertEquals ("Decrypt-" + data, data, decdata);
1013
1014                         sb.Append ("a");
1015                         data = sb.ToString ();
1016                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1017                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1018                         AssertEquals ("Encrypt-" + data, "lBehBplIrjjrlIrMjYcNz1DOoXLHjZdn", encdata);
1019                         AssertEquals ("Decrypt-" + data, data, decdata);
1020
1021                         sb.Append ("a");
1022                         data = sb.ToString ();
1023                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1024                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1025                         AssertEquals ("Encrypt-" + data, "2elWrUnjmsAOpo2s4voJyZXEJ/rtKB7P", encdata);
1026                         AssertEquals ("Decrypt-" + data, data, decdata);
1027
1028                         sb.Append ("a");
1029                         data = sb.ToString ();
1030                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1031                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1032                         AssertEquals ("Encrypt-" + data, "GB3BaIZGf9K+T82j7T8Fri2rQ2/YUdSe", encdata);
1033                         AssertEquals ("Decrypt-" + data, data, decdata);
1034
1035                         sb.Append ("a");
1036                         data = sb.ToString ();
1037                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1038                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1039                         AssertEquals ("Encrypt-" + data, "Gc+wkJL+CVjdJchgcIoi8dkH2BVpHJgB", encdata);
1040                         AssertEquals ("Decrypt-" + data, data, decdata);
1041
1042                         sb.Append ("a");
1043                         data = sb.ToString ();
1044                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1045                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1046                         AssertEquals ("Encrypt-" + data, "loeuyII/PvWb91M4pFVkyaPxQoQVYpNb", encdata);
1047                         AssertEquals ("Decrypt-" + data, data, decdata);
1048
1049                         sb.Append ("a");
1050                         data = sb.ToString ();
1051                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1052                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1053                         AssertEquals ("Encrypt-" + data, "PHXmi/sxNIgApXAfdm+Bf54/nCM//N8o", encdata);
1054                         AssertEquals ("Decrypt-" + data, data, decdata);
1055
1056                         sb.Append ("a");
1057                         data = sb.ToString ();
1058                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1059                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1060                         AssertEquals ("Encrypt-" + data, "xpb+wj/8LmH2ScTg3OU4JOsE5Owj6flF", encdata);
1061                         AssertEquals ("Decrypt-" + data, data, decdata);
1062
1063                         sb.Append ("a");
1064                         data = sb.ToString ();
1065                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1066                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1067                         AssertEquals ("Encrypt-" + data, "WJz4VfsZ2emzhYWoSf+PNBDpHooxEregqMWnzm4gcqU=", encdata);
1068                         AssertEquals ("Decrypt-" + data, data, decdata);
1069
1070                         sb.Append ("a");
1071                         data = sb.ToString ();
1072                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1073                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1074                         AssertEquals ("Encrypt-" + data, "PaouZu1iOKbCMRJSu04y/kB+TcOk4yp8K2BOGDs1PPE=", encdata);
1075                         AssertEquals ("Decrypt-" + data, data, decdata);
1076
1077                         sb.Append ("a");
1078                         data = sb.ToString ();
1079                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1080                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1081                         AssertEquals ("Encrypt-" + data, "qbTDs4dFy7eERdn5vV7JRPk2/m9smtwvZjA6+TmGlkI=", encdata);
1082                         AssertEquals ("Decrypt-" + data, data, decdata);
1083
1084                         sb.Append ("a");
1085                         data = sb.ToString ();
1086                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1087                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1088                         AssertEquals ("Encrypt-" + data, "f2FsphcpM7Fu90S5V17ptly44lL4GvFCCaFdnnU4twk=", encdata);
1089                         AssertEquals ("Decrypt-" + data, data, decdata);
1090
1091                         sb.Append ("a");
1092                         data = sb.ToString ();
1093                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1094                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1095                         AssertEquals ("Encrypt-" + data, "imD+ntHsUmp9ALJedzC1JmAJY0r2O4KkP8271+XuG4g=", encdata);
1096                         AssertEquals ("Decrypt-" + data, data, decdata);
1097
1098                         sb.Append ("a");
1099                         data = sb.ToString ();
1100                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1101                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1102                         AssertEquals ("Encrypt-" + data, "80QLLUmHwx1fcEYGeFz1WXlS13kUy994sQLI6GhcjuM=", encdata);
1103                         AssertEquals ("Decrypt-" + data, data, decdata);
1104
1105                         sb.Append ("a");
1106                         data = sb.ToString ();
1107                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1108                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1109                         AssertEquals ("Encrypt-" + data, "DtIIlj8BCOppmIgQ9AEdUj7pBB49S/9Q38kbWLjwiVs=", encdata);
1110                         AssertEquals ("Decrypt-" + data, data, decdata);
1111
1112                         sb.Append ("a");
1113                         data = sb.ToString ();
1114                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1115                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1116                         AssertEquals ("Encrypt-" + data, "LNkprYaaUFtyan204OzX+a2pzOb/Pg5WXzXJ6WWB1rQ=", encdata);
1117                         AssertEquals ("Decrypt-" + data, data, decdata);
1118
1119                         sb.Append ("a");
1120                         data = sb.ToString ();
1121                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1122                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1123                         AssertEquals ("Encrypt-" + data, "FRgx9m2lT2PxtYSIdRwc+SznJetNiRk1MEIZDl3D13pvo2yOtJ1MSQ==", encdata);
1124                         AssertEquals ("Decrypt-" + data, data, decdata);
1125
1126                         sb.Append ("a");
1127                         data = sb.ToString ();
1128                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1129                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1130                         AssertEquals ("Encrypt-" + data, "V7JlnpJscrdIpX4z5S+/Q5WDjKzK4aB5TiqI3JZOYJ+KE1CWQNNeow==", encdata);
1131                         AssertEquals ("Decrypt-" + data, data, decdata);
1132
1133                         sb.Append ("a");
1134                         data = sb.ToString ();
1135                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1136                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1137                         AssertEquals ("Encrypt-" + data, "wVwPv1c2KQynbwiOBCAhmQlReOQT52qFR34AX4dtjEeQ1oCQ1N1tHg==", encdata);
1138                         AssertEquals ("Decrypt-" + data, data, decdata);
1139
1140                         sb.Append ("a");
1141                         data = sb.ToString ();
1142                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1143                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1144                         AssertEquals ("Encrypt-" + data, "Zi+G0yfmuFjSjP455pjVeKBDDWB4qvTb0K0h20UtflrYG6wcWqUzDw==", encdata);
1145                         AssertEquals ("Decrypt-" + data, data, decdata);
1146
1147                         sb.Append ("a");
1148                         data = sb.ToString ();
1149                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1150                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1151                         AssertEquals ("Encrypt-" + data, "0hGoonZ8jrLhMNDKBuWrlvFnq15ZLvnyq+Ilq8r4aYUEDxttQMwi5w==", encdata);
1152                         AssertEquals ("Decrypt-" + data, data, decdata);
1153                 }
1154
1155                 // based on System.Security assembly XmlDsigBase64TransformTest
1156
1157                 [Test]
1158                 public void FromBase64_Write () 
1159                 {
1160                         string expected = "http://www.go-mono.com/";
1161                         byte[] data = Encoding.UTF8.GetBytes (expected);
1162                         string temp = Convert.ToBase64String (data, 0, data.Length);
1163                         data = Encoding.UTF8.GetBytes (temp);
1164
1165                         DebugStream debug = new DebugStream ();
1166                         ICryptoTransform base64 = new FromBase64Transform ();
1167                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1168                         cs.Write (data, 0, data.Length);
1169                         cs.FlushFinalBlock ();
1170                         byte[] encoded = debug.ToArray ();
1171
1172                         string result = Encoding.UTF8.GetString (encoded);
1173                         AssertEquals ("FromBase64_Write", expected, result);
1174                 }
1175
1176                 [Test]
1177                 public void FromBase64_Read () 
1178                 {
1179                         byte[] original = Encoding.UTF8.GetBytes ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=");
1180                         DebugStream debug = new DebugStream (original);
1181
1182                         ICryptoTransform base64 = new FromBase64Transform ();
1183                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1184                         
1185                         byte[] data = new byte [1024];
1186                         int length = cs.Read (data, 0, data.Length);
1187                         cs.Close ();
1188
1189                         string result = Encoding.UTF8.GetString (data, 0, length);
1190                         AssertEquals ("ToBase64_Read", "http://www.go-mono.com/", result);
1191                 }
1192
1193                 [Test]
1194                 public void ToBase64_Write () 
1195                 {
1196                         byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1197
1198                         DebugStream debug = new DebugStream ();
1199                         ICryptoTransform base64 = new ToBase64Transform ();
1200                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1201                         cs.Write (data, 0, data.Length);
1202                         cs.FlushFinalBlock ();
1203                         byte[] encoded = debug.ToArray ();
1204
1205                         string result = Encoding.UTF8.GetString (encoded);
1206                         AssertEquals ("ToBase64_Write", "aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result);
1207                 }
1208
1209                 [Test]
1210                 public void ToBase64_Read () 
1211                 {
1212                         byte[] original = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1213                         DebugStream debug = new DebugStream (original);
1214
1215                         ICryptoTransform base64 = new ToBase64Transform ();
1216                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1217                         
1218                         byte[] data = new byte [1024];
1219                         int length = cs.Read (data, 0, data.Length);
1220                         cs.Close ();
1221
1222                         string result = Encoding.UTF8.GetString (data, 0, length);
1223                         AssertEquals ("ToBase64_Read", "aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result);
1224                 }
1225
1226                 // Cascaded CryptoStream - like sample in book .NET Framework Security, chapter 30
1227
1228                 [Test]
1229                 public void CascadedCryptoStream_Write () 
1230                 {
1231                         DebugStream debug = new DebugStream ();
1232
1233                         // calculate both the hash (before encryption) and encrypt in one Write operation
1234                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1235                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1236                         DES des = DES.Create ();
1237                         CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1238
1239                         MD5 hash = MD5.Create ();
1240                         CryptoStream csh = new CryptoStream (cse, hash, CryptoStreamMode.Write);
1241
1242                         byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1243                         csh.Write (data, 0, data.Length);
1244                         csh.FlushFinalBlock ();
1245
1246                         byte[] result = debug.ToArray ();
1247                         AssertEquals ("Encrypted", "8C-24-76-74-09-79-2B-D3-47-C3-32-F5-F3-1A-5E-57-04-33-2E-B8-50-77-B2-A1", BitConverter.ToString (result));
1248                         byte[] digest = hash.Hash;
1249                         AssertEquals ("Hash", "71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest));
1250                 }
1251
1252                 [Test]
1253                 public void CascadedCryptoStream_Read () 
1254                 {
1255                         byte[] encdata = new byte[] { 0x8C, 0x24, 0x76, 0x74, 0x09, 0x79, 0x2B, 0xD3, 0x47, 0xC3, 0x32, 0xF5, 0xF3, 0x1A, 0x5E, 0x57, 0x04, 0x33, 0x2E, 0xB8, 0x50, 0x77, 0xB2, 0xA1 };
1256                         DebugStream debug = new DebugStream (encdata);
1257
1258                         // decrypt data and validate its hash in one Read operation
1259                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1260                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1261                         DES des = DES.Create ();
1262                         CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
1263
1264                         MD5 hash = MD5.Create ();
1265                         CryptoStream csh = new CryptoStream (csd, hash, CryptoStreamMode.Read);
1266
1267                         byte[] data = new byte [1024];
1268                         int length = csh.Read (data, 0, data.Length);
1269                         csh.Close ();
1270                         
1271                         string result = Encoding.UTF8.GetString (data, 0, length);
1272                         AssertEquals ("Decrypted", "http://www.go-mono.com/", result);
1273                         byte[] digest = hash.Hash;
1274                         AssertEquals ("Hash Validation", "71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest));
1275                 }
1276
1277                 // bugzilla: 60573 - the number of block is not reduced for encryptors
1278
1279                 [Test]
1280                 public void EncryptorWriteBlocks () 
1281                 {
1282                         DebugStream debug = new DebugStream ();
1283
1284                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1285                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1286                         DES des = DES.Create ();
1287                         CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1288
1289                         byte[] data = new byte [64];
1290                         cse.Write (data, 0, 64);
1291                         AssertEquals ("Length", 64, debug.Length);
1292                         cse.Close ();
1293                 }
1294
1295                 [Test]
1296                 public void DecryptorWriteBlocks () 
1297                 {
1298                         DebugStream debug = new DebugStream ();
1299
1300                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1301                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1302                         DES des = DES.Create ();
1303                         CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Write);
1304
1305                         byte[] data = new byte [64] { 0xE1, 0xB2, 0x46, 0xE5, 0xA7, 0xC7, 0x4C, 0xBC, 0xD5, 0xF0, 0x8E, 0x25, 0x3B, 0xFA, 0x23, 0x80, 0x03, 0x16, 0x18, 0x17, 0xA3, 0x59, 0xBA, 0xAC, 0xFC, 0x47, 0x57, 0x2A, 0xF9, 0x44, 0x07, 0x84, 0x20, 0x74, 0x06, 0x38, 0xC2, 0xF3, 0xA1, 0xCE, 0x8C, 0x73, 0xB1, 0xE3, 0x75, 0x03, 0x66, 0x89, 0xF0, 0x4E, 0x98, 0x68, 0xB1, 0xBD, 0x85, 0x25, 0xFF, 0x4B, 0x11, 0x74, 0xEF, 0x14, 0xC8, 0xE9 };
1306                         csd.Write (data, 0, 64);
1307                         AssertEquals ("Length", 56, debug.Length);
1308                         // last block is kept for later processing
1309                 }
1310         }
1311 }