2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / Test / System.Security.Cryptography / MACTripleDESTest.cs
1 //
2 // MACTripleDESTest.cs - NUnit Test Cases for MACTripleDES
3 //
4 // Author:
5 //      Sebastien Pouliot (sebastien@ximian.com)
6 //
7 // (C) 2002, 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 using NUnit.Framework;
31 using System;
32 using System.IO;
33 using System.Security.Cryptography;
34
35 namespace MonoTests.System.Security.Cryptography {
36
37 [TestFixture]
38 public class MACTripleDESTest : Assertion {
39
40         protected MACTripleDES algo;
41
42         private static byte[] key1 = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
43         private static byte[] key2 = { 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01 };
44         private static byte[] key3 = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
45
46         public void AssertEquals (string msg, byte[] array1, byte[] array2) 
47         {
48                 AllTests.AssertEquals (msg, array1, array2);
49         }
50
51         protected byte[] CombineKeys (byte[] key1, byte[] key2, byte[] key3) 
52         {
53                 int k1l = key1.Length;
54                 int k2l = key2.Length;
55                 int k3l = key3.Length;
56                 byte[] key = new byte [k1l + k2l + k3l];
57                 Array.Copy (key1, 0, key, 0, k1l);
58                 Array.Copy (key2, 0, key, k1l, k2l);
59                 Array.Copy (key3, 0, key, k1l + k2l, k3l);
60                 return key;
61         }
62
63         [Test]
64         public void ConstructorEmpty () 
65         {
66                 algo = new MACTripleDES ();
67                 AssertNotNull ("MACTripleDES ()", algo);
68         }
69
70         [Test]
71         public void ConstructorKey () 
72         {
73                 byte[] key = CombineKeys (key1, key2, key3);
74                 algo = new MACTripleDES (key);
75                 AssertNotNull ("MACTripleDES (key)", algo);
76         }
77
78         [Test]
79         [ExpectedException (typeof (ArgumentNullException))]
80         public void ConstructorKeyNull () 
81         {
82                 algo = new MACTripleDES (null);
83         }
84
85         [Test]
86         public void ConstructorNameKey () 
87         {
88                 byte[] key = CombineKeys (key1, key2, key3);
89                 algo = new MACTripleDES ("TripleDES", key);
90                 AssertNotNull ("MACTripleDES ('TripleDES',key)", algo);
91         }
92
93         [Test]
94         // LAMESPEC: [ExpectedException (typeof (ArgumentNullException))]
95         public void ConstructorNameNullKey () 
96         {
97                 byte[] key = CombineKeys (key1, key2, key3);
98                 // funny null is a valid name!
99                 algo = new MACTripleDES (null, key);
100                 AssertNotNull ("MACTripleDES (null,key)", algo);
101         }
102
103         [Test]
104         [ExpectedException (typeof (ArgumentNullException))]
105         public void ConstructorNameNullKeyNull () 
106         {
107                 algo = new MACTripleDES (null, null);
108         }
109
110         [Test]
111         public void Invariants () 
112         {
113                 algo = new MACTripleDES ();
114                 AssertEquals ("MACTripleDES.CanReuseTransform", true, algo.CanReuseTransform);
115                 AssertEquals ("MACTripleDES.CanTransformMultipleBlocks", true, algo.CanTransformMultipleBlocks);
116                 AssertEquals ("MACTripleDES.HashSize", 64, algo.HashSize);
117                 AssertEquals ("MACTripleDES.InputBlockSize", 1, algo.InputBlockSize);
118                 AssertEquals ("MACTripleDES.OutputBlockSize", 1, algo.OutputBlockSize);
119                 AssertEquals ("MACTripleDES.ToString()", "System.Security.Cryptography.MACTripleDES", algo.ToString ()); 
120                 AssertNotNull ("MACTripleDES.Key", algo.Key);
121         }
122
123         [Test]
124         [ExpectedException (typeof (InvalidCastException))]
125         public void InvalidAlgorithmName () 
126         {
127                 byte[] key = CombineKeys (key1, key2, key3);
128                 algo = new MACTripleDES ("DES", key);
129         }
130
131         [Test]
132         [ExpectedException (typeof (ObjectDisposedException))]
133         public void ObjectDisposed () 
134         {
135                 byte[] key = CombineKeys (key1, key2, key3);
136                 algo = new MACTripleDES (key);
137                 algo.Clear ();
138                 algo.ComputeHash (new byte[1]);
139         }
140
141         public void Check (string testName, byte[] key, byte[] data, byte[] result) 
142         {
143                 string classTestName = "MACTripleDES-" + testName;
144                 CheckA (testName, key, data, result);
145                 CheckB (testName, key, data, result);
146                 CheckC (testName, key, data, result);
147                 CheckD (testName, key, data, result);
148                 CheckE (testName, key, data, result);
149         }
150
151         // - Test constructor #1 ()
152         // - Test ComputeHash (byte[]);
153         public void CheckA (string testName, byte[] key, byte[] data, byte[] result) 
154         {
155                 algo = new MACTripleDES ();
156                 algo.Key = key;
157                 byte[] hmac = algo.ComputeHash (data);
158                 AssertEquals (testName + "a1", result, hmac);
159                 AssertEquals (testName + "a2", result, algo.Hash);
160         }
161
162         // - Test constructor #2 (byte[])
163         // - Test ComputeHash (byte[], int, int);
164         public void CheckB (string testName, byte[] key, byte[] data, byte[] result) 
165         {
166                 algo = new MACTripleDES (key);
167                 byte[] hmac = algo.ComputeHash (data, 0, data.Length);
168                 AssertEquals (testName + "b1", result, hmac);
169                 AssertEquals (testName + "b2", result, algo.Hash);
170         }
171         
172         // - Test constructor #3 (string, byte[])
173         // - Test ComputeHash (stream);
174         public void CheckC (string testName, byte[] key, byte[] data, byte[] result) 
175         {
176                 algo = new MACTripleDES ("TripleDES", key);
177                 algo.Key = key;
178                 MemoryStream ms = new MemoryStream (data);
179                 byte[] hmac = algo.ComputeHash (ms);
180                 AssertEquals (testName + "c1", result, hmac);
181                 AssertEquals (testName + "c2", result, algo.Hash);
182         }
183
184         // - Test TransformFinalBlock - alone;
185         public void CheckD (string testName, byte[] key, byte[] data, byte[] result) 
186         {
187                 algo = new MACTripleDES ();
188                 algo.Key = key;
189                 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
190                 algo.TransformFinalBlock (data, 0, data.Length);
191                 AssertEquals (testName + "d", result, algo.Hash);
192         }
193
194         // - Test TransformBlock/TransformFinalBlock
195         public void CheckE (string testName, byte[] key, byte[] data, byte[] result) 
196         {
197                 algo = new MACTripleDES ();
198                 algo.Key = key;
199                 byte[] copy = new byte [data.Length];
200                 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
201                 for (int i=0; i < data.Length - 1; i++)
202                         algo.TransformBlock (data, i, 1, copy, i);
203                 algo.TransformFinalBlock (data, data.Length - 1, 1);
204                 AssertEquals (testName + "e", result, algo.Hash);
205         }
206
207         // Here data is smaller than the 3DES block size (8 bytes)
208         [Test]
209         public void SmallerThanOneBlockSize () 
210         {
211                 byte[] key = CombineKeys (key1, key2, key3);
212                 byte[] expected = { 0x86, 0xE9, 0x65, 0xBD, 0x1E, 0xC4, 0x44, 0x61 };
213                 byte[] data = new byte [7];
214                 Check ("3DESMAC-A1", key, data, expected);
215         }
216
217         // Here data is exactly one 3DES block size (8 bytes)
218         [Test]
219         public void ExactlyOneBlockSize () 
220         {
221                 byte[] key = CombineKeys (key1, key2, key3);
222 #if NET_1_1
223                 byte [] expected = { 0x86, 0xE9, 0x65, 0xBD, 0x1E, 0xC4, 0x44, 0x61 };
224 #else
225                 // Believe it or not, MACTripleDES returns different values in 1.1
226                 byte[] expected = { 0x23, 0xD6, 0x92, 0xA0, 0x80, 0x6E, 0xC9, 0x30 };
227 #endif
228                 byte[] data = new byte [8];
229                 Check ("3DESMAC-A2", key, data, expected);
230         }
231
232         // Here data is more then one 3DES block size (8 bytes)
233         [Test]
234         public void MoreThanOneBlockSize () 
235         {
236                 byte[] key = CombineKeys (key1, key2, key3);
237                 // note: same result as A2 because of the Zero padding (and that
238                 // we use zeros as data
239                 byte[] expected = { 0x23, 0xD6, 0x92, 0xA0, 0x80, 0x6E, 0xC9, 0x30 };
240                 byte[] data = new byte [14];
241                 Check ("3DESMAC-A3", key, data, expected);
242         }
243
244         // Here data is a multiple of 3DES block size (8 bytes)
245         [Test]
246         public void ExactMultipleBlockSize () 
247         {
248                 byte[] key = CombineKeys (key1, key2, key3);
249 #if NET_1_1
250                 byte [] expected = { 0xA3, 0x0E, 0x34, 0x26, 0x8B, 0x49, 0xEF, 0x49 };
251 #else
252                 // Believe it or not, MACTripleDES returns different values in 1.1
253                 byte[] expected = { 0xD6, 0x6D, 0x75, 0xD4, 0x75, 0xF1, 0x01, 0x71 };
254 #endif
255                 byte[] data = new byte [48];
256                 Check ("3DESMAC-A4", key, data, expected);
257         }
258 }
259
260 }