**** Merged from MCS ****
[mono-project.git] / mcs / class / Mono.Security / Test / Mono.Security.Cryptography / ARC4ManagedTest.cs
blobe2c9e9fac9cec1fe1e0755742900c508b4a4923c
1 //
2 // ARC4ManagedTest.cs - NUnit Test Cases for Alleged RC4(tm)
3 // RC4 is a trademark of RSA Security
4 //
5 // Author:
6 // Sebastien Pouliot (spouliot@motus.com)
7 //
8 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
9 //
11 using NUnit.Framework;
12 using System;
13 using System.Security.Cryptography;
14 using Mono.Security.Cryptography;
16 namespace MonoTests.Mono.Security.Cryptography {
18 // References
19 // a. Usenet 1994 - RC4 Algorithm revealed
20 // http://www.qrst.de/html/dsds/rc4.htm
21 // b. Netscape SSL version 3 implementation details
22 // Export Client SSL Connection Details
23 // http://wp.netscape.com/eng/ssl3/traces/trc-clnt-ex.html
25 [TestFixture]
26 public class ARC4ManagedTest : Assertion {
28 // because most crypto stuff works with byte[] buffers
29 static public void AssertEquals (string msg, byte[] array1, byte[] array2)
31 if ((array1 == null) && (array2 == null))
32 return;
33 if (array1 == null)
34 Fail (msg + " -> First array is NULL");
35 if (array2 == null)
36 Fail (msg + " -> Second array is NULL");
38 bool a = (array1.Length == array2.Length);
39 if (a) {
40 for (int i = 0; i < array1.Length; i++) {
41 if (array1 [i] != array2 [i]) {
42 a = false;
43 break;
47 msg += " -> Expected " + BitConverter.ToString (array1, 0);
48 msg += " is different than " + BitConverter.ToString (array2, 0);
49 Assert (msg, a);
52 // from ref. a
53 [Test]
54 public void Vector0 ()
56 byte[] key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
57 byte[] input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
58 byte[] expected = { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 };
59 ARC4Managed rc4 = new ARC4Managed ();
60 rc4.Key = key;
61 ICryptoTransform stream = rc4.CreateEncryptor ();
62 byte[] output = stream.TransformFinalBlock (input, 0, input.Length);
63 AssertEquals ("RC4 - Test Vector 0", expected, output);
66 // from ref. a
67 [Test]
68 public void Vector1 ()
70 byte[] key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
71 byte[] input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
72 byte[] expected = { 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79 };
73 ARC4Managed rc4 = new ARC4Managed ();
74 rc4.Key = key;
75 ICryptoTransform stream = rc4.CreateEncryptor ();
76 byte[] output = stream.TransformFinalBlock (input, 0, input.Length);
77 AssertEquals ("RC4 - Test Vector 1", expected, output);
80 // from ref. a
81 [Test]
82 public void Vector2 ()
84 byte[] key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
85 byte[] input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
86 byte[] expected = { 0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a };
87 ARC4Managed rc4 = new ARC4Managed ();
88 rc4.Key = key;
89 ICryptoTransform stream = rc4.CreateEncryptor ();
90 byte[] output = stream.TransformFinalBlock (input, 0, input.Length);
91 AssertEquals ("RC4 - Test Vector 2", expected, output);
94 // from ref. a
95 [Test]
96 public void Vector3 ()
98 byte[] key = { 0xef, 0x01, 0x23, 0x45 };
99 byte[] input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
100 byte[] expected = { 0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, 0xbd, 0x61 };
101 ARC4Managed rc4 = new ARC4Managed ();
102 rc4.Key = key;
103 ICryptoTransform stream = rc4.CreateEncryptor ();
104 byte[] output = stream.TransformFinalBlock (input, 0, input.Length);
105 AssertEquals ("RC4 - Test Vector 3", expected, output);
108 // from ref. a
109 [Test]
110 public void Vector4 ()
112 byte[] key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
113 byte[] input = new byte [512];
114 for (int i=0; i < input.Length; i++)
115 input [i] = 0x01;
116 byte[] expected = { 0x75, 0x95, 0xc3, 0xe6, 0x11, 0x4a, 0x09, 0x78, 0x0c, 0x4a, 0xd4,
117 0x52, 0x33, 0x8e, 0x1f, 0xfd, 0x9a, 0x1b, 0xe9, 0x49, 0x8f,
118 0x81, 0x3d, 0x76, 0x53, 0x34, 0x49, 0xb6, 0x77, 0x8d, 0xca,
119 0xd8, 0xc7, 0x8a, 0x8d, 0x2b, 0xa9, 0xac, 0x66, 0x08, 0x5d,
120 0x0e, 0x53, 0xd5, 0x9c, 0x26, 0xc2, 0xd1, 0xc4, 0x90, 0xc1,
121 0xeb, 0xbe, 0x0c, 0xe6, 0x6d, 0x1b, 0x6b, 0x1b, 0x13, 0xb6,
122 0xb9, 0x19, 0xb8, 0x47, 0xc2, 0x5a, 0x91, 0x44, 0x7a, 0x95,
123 0xe7, 0x5e, 0x4e, 0xf1, 0x67, 0x79, 0xcd, 0xe8, 0xbf, 0x0a,
124 0x95, 0x85, 0x0e, 0x32, 0xaf, 0x96, 0x89, 0x44, 0x4f, 0xd3,
125 0x77, 0x10, 0x8f, 0x98, 0xfd, 0xcb, 0xd4, 0xe7, 0x26, 0x56,
126 0x75, 0x00, 0x99, 0x0b, 0xcc, 0x7e, 0x0c, 0xa3, 0xc4, 0xaa,
127 0xa3, 0x04, 0xa3, 0x87, 0xd2, 0x0f, 0x3b, 0x8f, 0xbb, 0xcd,
128 0x42, 0xa1, 0xbd, 0x31, 0x1d, 0x7a, 0x43, 0x03, 0xdd, 0xa5,
129 0xab, 0x07, 0x88, 0x96, 0xae, 0x80, 0xc1, 0x8b, 0x0a, 0xf6,
130 0x6d, 0xff, 0x31, 0x96, 0x16, 0xeb, 0x78, 0x4e, 0x49, 0x5a,
131 0xd2, 0xce, 0x90, 0xd7, 0xf7, 0x72, 0xa8, 0x17, 0x47, 0xb6,
132 0x5f, 0x62, 0x09, 0x3b, 0x1e, 0x0d, 0xb9, 0xe5, 0xba, 0x53,
133 0x2f, 0xaf, 0xec, 0x47, 0x50, 0x83, 0x23, 0xe6, 0x71, 0x32,
134 0x7d, 0xf9, 0x44, 0x44, 0x32, 0xcb, 0x73, 0x67, 0xce, 0xc8,
135 0x2f, 0x5d, 0x44, 0xc0, 0xd0, 0x0b, 0x67, 0xd6, 0x50, 0xa0,
136 0x75, 0xcd, 0x4b, 0x70, 0xde, 0xdd, 0x77, 0xeb, 0x9b, 0x10,
137 0x23, 0x1b, 0x6b, 0x5b, 0x74, 0x13, 0x47, 0x39, 0x6d, 0x62,
138 0x89, 0x74, 0x21, 0xd4, 0x3d, 0xf9, 0xb4, 0x2e, 0x44, 0x6e,
139 0x35, 0x8e, 0x9c, 0x11, 0xa9, 0xb2, 0x18, 0x4e, 0xcb, 0xef,
140 0x0c, 0xd8, 0xe7, 0xa8, 0x77, 0xef, 0x96, 0x8f, 0x13, 0x90,
141 0xec, 0x9b, 0x3d, 0x35, 0xa5, 0x58, 0x5c, 0xb0, 0x09, 0x29,
142 0x0e, 0x2f, 0xcd, 0xe7, 0xb5, 0xec, 0x66, 0xd9, 0x08, 0x4b,
143 0xe4, 0x40, 0x55, 0xa6, 0x19, 0xd9, 0xdd, 0x7f, 0xc3, 0x16,
144 0x6f, 0x94, 0x87, 0xf7, 0xcb, 0x27, 0x29, 0x12, 0x42, 0x64,
145 0x45, 0x99, 0x85, 0x14, 0xc1, 0x5d, 0x53, 0xa1, 0x8c, 0x86,
146 0x4c, 0xe3, 0xa2, 0xb7, 0x55, 0x57, 0x93, 0x98, 0x81, 0x26,
147 0x52, 0x0e, 0xac, 0xf2, 0xe3, 0x06, 0x6e, 0x23, 0x0c, 0x91,
148 0xbe, 0xe4, 0xdd, 0x53, 0x04, 0xf5, 0xfd, 0x04, 0x05, 0xb3,
149 0x5b, 0xd9, 0x9c, 0x73, 0x13, 0x5d, 0x3d, 0x9b, 0xc3, 0x35,
150 0xee, 0x04, 0x9e, 0xf6, 0x9b, 0x38, 0x67, 0xbf, 0x2d, 0x7b,
151 0xd1, 0xea, 0xa5, 0x95, 0xd8, 0xbf, 0xc0, 0x06, 0x6f, 0xf8,
152 0xd3, 0x15, 0x09, 0xeb, 0x0c, 0x6c, 0xaa, 0x00, 0x6c, 0x80,
153 0x7a, 0x62, 0x3e, 0xf8, 0x4c, 0x3d, 0x33, 0xc1, 0x95, 0xd2,
154 0x3e, 0xe3, 0x20, 0xc4, 0x0d, 0xe0, 0x55, 0x81, 0x57, 0xc8,
155 0x22, 0xd4, 0xb8, 0xc5, 0x69, 0xd8, 0x49, 0xae, 0xd5, 0x9d,
156 0x4e, 0x0f, 0xd7, 0xf3, 0x79, 0x58, 0x6b, 0x4b, 0x7f, 0xf6,
157 0x84, 0xed, 0x6a, 0x18, 0x9f, 0x74, 0x86, 0xd4, 0x9b, 0x9c,
158 0x4b, 0xad, 0x9b, 0xa2, 0x4b, 0x96, 0xab, 0xf9, 0x24, 0x37,
159 0x2c, 0x8a, 0x8f, 0xff, 0xb1, 0x0d, 0x55, 0x35, 0x49, 0x00,
160 0xa7, 0x7a, 0x3d, 0xb5, 0xf2, 0x05, 0xe1, 0xb9, 0x9f, 0xcd,
161 0x86, 0x60, 0x86, 0x3a, 0x15, 0x9a, 0xd4, 0xab, 0xe4, 0x0f,
162 0xa4, 0x89, 0x34, 0x16, 0x3d, 0xdd, 0xe5, 0x42, 0xa6, 0x58,
163 0x55, 0x40, 0xfd, 0x68, 0x3c, 0xbf, 0xd8, 0xc0, 0x0f, 0x12,
164 0x12, 0x9a, 0x28, 0x4d, 0xea, 0xcc, 0x4c, 0xde, 0xfe, 0x58,
165 0xbe, 0x71, 0x37, 0x54, 0x1c, 0x04, 0x71, 0x26, 0xc8, 0xd4,
166 0x9e, 0x27, 0x55, 0xab, 0x18, 0x1a, 0xb7, 0xe9, 0x40, 0xb0,
167 0xc0 };
168 ARC4Managed rc4 = new ARC4Managed ();
169 rc4.Key = key;
170 ICryptoTransform stream = rc4.CreateEncryptor ();
171 byte[] output = stream.TransformFinalBlock (input, 0, input.Length);
172 AssertEquals ("RC4 - Test Vector 4", expected, output);
175 static byte[] clientWriteKey = { 0x32, 0x10, 0xcd, 0xe1, 0xd6, 0xdc, 0x07, 0x83, 0xf3, 0x75, 0x4c, 0x32, 0x2e, 0x59, 0x96, 0x61 };
176 static byte[] serverWriteKey = { 0xed, 0x0e, 0x56, 0xc8, 0x95, 0x12, 0x37, 0xb6, 0x21, 0x17, 0x1c, 0x72, 0x79, 0x91, 0x12, 0x1e };
178 // SSL3 Client's Finished Handshake (from ref. b)
179 [Test]
180 public void SSLClient ()
182 byte[] data = { 0x14, 0x00, 0x00, 0x24, 0xf2, 0x40, 0x10, 0x3f, 0x74, 0x63, 0xea, 0xe8, 0x7a, 0x27, 0x23, 0x56, 0x5f, 0x59, 0x07, 0xd2, 0xa3, 0x79, 0x5d, 0xb7, 0x8b, 0x94, 0xdb, 0xcf, 0xfa, 0xf5, 0x18, 0x22, 0x15, 0x7b, 0xf2, 0x4a, 0x96, 0x52, 0x9a, 0x0e, 0xd3, 0x09, 0xde, 0x28, 0x84, 0xa7, 0x07, 0x5c, 0x7c, 0x0c, 0x08, 0x85, 0x6b, 0x4f, 0x63, 0x04 };
183 ARC4Managed rc4 = new ARC4Managed ();
184 rc4.Key = clientWriteKey;
185 // encrypt inplace (in same buffer)
186 rc4.TransformBlock (data, 0, data.Length, data, 0);
187 byte[] expectedData = { 0xed, 0x37, 0x7f, 0x16, 0xd3, 0x11, 0xe8, 0xa3, 0xe1, 0x2a, 0x20, 0xb7, 0x88, 0xf6, 0x11, 0xf3, 0xa6, 0x7d, 0x37, 0xf7, 0x17, 0xac, 0x67, 0x20, 0xb8, 0x0e, 0x88, 0xd1, 0xa0, 0xc6, 0x83, 0xe4, 0x80, 0xe8, 0xc7, 0xe3, 0x0b, 0x91, 0x29, 0x30, 0x29, 0xe4, 0x28, 0x47, 0xb7, 0x40, 0xa4, 0xd1, 0x3c, 0xda, 0x82, 0xb7, 0xb3, 0x9f, 0x67, 0x10 };
188 AssertEquals ("RC4 - Client's Finished Handshake", expectedData, data);
191 // SSL3 Server Finished Handshake (from ref. b)
192 [Test]
193 public void SSLServer ()
195 byte[] encryptedData = { 0x54, 0x3c, 0xe1, 0xe7, 0x4d, 0x77, 0x76, 0x62, 0x86, 0xfa, 0x4e, 0x0a, 0x6f, 0x5f, 0x6a, 0x3d, 0x43, 0x26, 0xf4, 0xad, 0x8d, 0x3e, 0x09, 0x0b, 0x2b, 0xf7, 0x9f, 0x49, 0x44, 0x92, 0xfb, 0xa9, 0xa4, 0xb0, 0x5a, 0xd8, 0x72, 0x77, 0x6e, 0x8b, 0xb3, 0x78, 0xfb, 0xda, 0xe0, 0x25, 0xef, 0xb3, 0xf5, 0xa7, 0x90, 0x08, 0x6d, 0x60, 0xd5, 0x4e };
196 ARC4Managed rc4 = new ARC4Managed ();
197 rc4.Key = serverWriteKey;
198 // decrypt inplace (in same buffer)
199 rc4.TransformBlock (encryptedData, 0, encryptedData.Length, encryptedData, 0);
200 byte[] expectedData = { 0x14, 0x00, 0x00, 0x24, 0xb7, 0xcc, 0xd6, 0x05, 0x6b, 0xfc, 0xfa, 0x6d, 0xfa, 0xdd, 0x76, 0x81, 0x45, 0x36, 0xe4, 0xf4, 0x26, 0x35, 0x72, 0x2c, 0xec, 0x87, 0x62, 0x1f, 0x55, 0x08, 0x05, 0x4f, 0xc8, 0xf5, 0x7c, 0x49, 0xe2, 0xee, 0xc5, 0xba, 0xbd, 0x69, 0x27, 0x3b, 0xd0, 0x13, 0x23, 0x52, 0xed, 0xec, 0x11, 0x55, 0xd8, 0xb9, 0x90, 0x8c };
201 AssertEquals ("RC4 - Server's Finished Handshake", expectedData, encryptedData);
204 [Test]
205 public void DefaultProperties ()
207 ARC4Managed rc4 = new ARC4Managed ();
208 Assert ("CanReuseTransform", !rc4.CanReuseTransform);
209 Assert ("CanTransformMultipleBlocks", rc4.CanTransformMultipleBlocks);
210 AssertEquals ("InputBlockSize", 1, rc4.InputBlockSize);
211 AssertEquals ("OutputBlockSize", 1, rc4.OutputBlockSize);
214 [Test]
215 public void DefaultSizes ()
217 ARC4Managed rc4 = new ARC4Managed ();
218 rc4.GenerateKey ();
219 rc4.GenerateIV ();
220 AssertEquals ("Key.Length", 16, rc4.Key.Length);
221 AssertEquals ("KeySize", 128, rc4.KeySize);
222 AssertEquals ("IV.Length", 0, rc4.IV.Length);
225 [Test]
226 [ExpectedException (typeof (ArgumentNullException))]
227 public void TransformBlock_InputBuffer_Null ()
229 byte[] output = new byte [1];
230 ARC4Managed rc4 = new ARC4Managed ();
231 rc4.TransformBlock (null, 0, 1, output, 0);
234 [Test]
235 [ExpectedException (typeof (ArgumentOutOfRangeException))]
236 public void TransformBlock_InputOffset_Negative ()
238 byte[] input = new byte [1];
239 byte[] output = new byte [1];
240 ARC4Managed rc4 = new ARC4Managed ();
241 rc4.TransformBlock (input, -1, 1, output, 0);
244 [Test]
245 [ExpectedException (typeof (ArgumentException))]
246 public void TransformBlock_InputOffset_Overflow ()
248 byte[] input = new byte [1];
249 byte[] output = new byte [1];
250 ARC4Managed rc4 = new ARC4Managed ();
251 rc4.TransformBlock (input, Int32.MaxValue, 1, output, 0);
254 [Test]
255 [ExpectedException (typeof (ArgumentOutOfRangeException))]
256 public void TransformBlock_InputCount_Negative ()
258 byte[] input = new byte [1];
259 byte[] output = new byte [1];
260 ARC4Managed rc4 = new ARC4Managed ();
261 rc4.TransformBlock (input, 0, -1, output, 0);
264 [Test]
265 [ExpectedException (typeof (ArgumentException))]
266 public void TransformBlock_InputCount_Overflow ()
268 byte[] input = new byte [1];
269 byte[] output = new byte [1];
270 ARC4Managed rc4 = new ARC4Managed ();
271 rc4.TransformBlock (input, 1, Int32.MaxValue, output, 0);
274 [Test]
275 [ExpectedException (typeof (ArgumentNullException))]
276 public void TransformBlock_OutputBuffer_Null ()
278 byte[] input = new byte [1];
279 ARC4Managed rc4 = new ARC4Managed ();
280 rc4.TransformBlock (input, 0, 1, null, 0);
283 [Test]
284 [ExpectedException (typeof (ArgumentOutOfRangeException))]
285 public void TransformBlock_OutputOffset_Negative ()
287 byte[] input = new byte [1];
288 byte[] output = new byte [1];
289 ARC4Managed rc4 = new ARC4Managed ();
290 rc4.TransformBlock (input, 0, 1, output, -1);
293 [Test]
294 [ExpectedException (typeof (ArgumentException))]
295 public void TransformBlock_OutputOffset_Overflow ()
297 byte[] input = new byte [1];
298 byte[] output = new byte [1];
299 ARC4Managed rc4 = new ARC4Managed ();
300 rc4.TransformBlock (input, 0, 1, output, Int32.MaxValue);
303 [Test]
304 [ExpectedException (typeof (ArgumentNullException))]
305 public void TransformFinalBlock_InputBuffer_Null ()
307 ARC4Managed rc4 = new ARC4Managed ();
308 rc4.TransformFinalBlock (null, 0, 1);
311 [Test]
312 [ExpectedException (typeof (ArgumentOutOfRangeException))]
313 public void TransformFinalBlock_InputOffset_Negative ()
315 byte[] input = new byte [1];
316 ARC4Managed rc4 = new ARC4Managed ();
317 rc4.TransformFinalBlock (input, -1, 1);
320 [Test]
321 [ExpectedException (typeof (ArgumentException))]
322 public void TransformFinalBlock_InputOffset_Overflow ()
324 byte[] input = new byte [1];
325 ARC4Managed rc4 = new ARC4Managed ();
326 rc4.TransformFinalBlock (input, Int32.MaxValue, 1);
329 [Test]
330 [ExpectedException (typeof (ArgumentOutOfRangeException))]
331 public void TransformFinalBlock_InputCount_Negative ()
333 byte[] input = new byte [1];
334 ARC4Managed rc4 = new ARC4Managed ();
335 rc4.TransformFinalBlock (input, 0, -1);
338 [Test]
339 [ExpectedException (typeof (ArgumentException))]
340 public void TransformFinalBlock_InputCount_Overflow ()
342 byte[] input = new byte [1];
343 ARC4Managed rc4 = new ARC4Managed ();
344 rc4.TransformFinalBlock (input, 1, Int32.MaxValue);