2 // TestSuite.System.Security.Cryptography.RijndaelManaged.cs
5 // Andrew Birkett (andy@nobugs.org)
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
12 using System.Security.Cryptography;
14 using NUnit.Framework;
16 namespace MonoTests.System.Security.Cryptography {
19 public class RijndaelManagedTest {
21 private RijndaelManaged aes;
26 aes = new RijndaelManaged ();
29 public void CheckCBC(ICryptoTransform encryptor, ICryptoTransform decryptor,
30 byte[] plaintext, byte[] expected)
33 if ((plaintext.Length % encryptor.InputBlockSize) != 0) {
34 throw new ArgumentException("Must have complete blocks");
37 byte[] ciphertext = new byte[plaintext.Length];
38 for (int i=0; i < plaintext.Length; i += encryptor.InputBlockSize) {
39 encryptor.TransformBlock(plaintext, i, encryptor.InputBlockSize, ciphertext, i);
41 Assert.AreEqual (expected, ciphertext, "CBC");
43 byte[] roundtrip = new byte[plaintext.Length];
44 for (int i=0; i < ciphertext.Length; i += decryptor.InputBlockSize) {
45 decryptor.TransformBlock(ciphertext, i, decryptor.InputBlockSize, roundtrip, i);
47 Assert.AreEqual (plaintext, roundtrip, "CBC-rt");
53 byte[] plaintext = new byte[32];
54 for (int i=0; i < plaintext.Length; i++) plaintext[i] = 0;
56 byte[] iv = new byte[16];
57 for (byte i=0; i < iv.Length; i++) {
61 RijndaelManaged r = new RijndaelManaged();
62 byte[] key = new byte[16];
64 for (int i=0; i < 16; i++) r.Key[i] = 0;
66 r.Mode = CipherMode.CBC;
67 r.Padding = PaddingMode.Zeros;
71 0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
72 0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e,
73 0xf7, 0x95, 0xbd, 0x4a, 0x52, 0xe2, 0x9e, 0xd7,
74 0x13, 0xd3, 0x13, 0xfa, 0x20, 0xe9, 0x8d, 0xbc };
76 CheckCBC(r.CreateEncryptor(key, iv), r.CreateDecryptor(key, iv), plaintext, expected);
82 byte[] plaintext = new byte[32];
83 for (int i=0; i < plaintext.Length; i++) plaintext[i] = 0;
85 byte[] iv = new byte[16];
86 for (byte i=0; i < iv.Length; i++) {
90 RijndaelManaged r = new RijndaelManaged();
91 byte[] key = new byte[16];
92 for (byte i=0; i < 16; i++) key[i] = 0;
96 r.Mode = CipherMode.CBC;
97 r.Padding = PaddingMode.Zeros;
100 0x7a, 0xca, 0x0f, 0xd9, 0xbc, 0xd6, 0xec, 0x7c,
101 0x9f, 0x97, 0x46, 0x66, 0x16, 0xe6, 0xa2, 0x82,
102 0x66, 0xc5, 0x84, 0x17, 0x1d, 0x3c, 0x20, 0x53,
103 0x6f, 0x0a, 0x09, 0xdc, 0x4d, 0x1e, 0x45, 0x3b };
105 CheckCBC(r.CreateEncryptor(key, iv), r.CreateDecryptor(key, iv), plaintext, expected);
108 public void CheckECBRoundtrip(ICryptoTransform encryptor, ICryptoTransform decryptor,
109 byte[] plaintext, byte[] expected)
111 byte[] ciphertext = new byte[plaintext.Length];
112 int n = encryptor.TransformBlock(plaintext, 0, plaintext.Length, ciphertext, 0);
114 Assert.AreEqual (expected, ciphertext, "ECB");
116 byte[] roundtrip = new byte[plaintext.Length];
117 n = decryptor.TransformBlock(ciphertext, 0, ciphertext.Length, roundtrip, 0);
119 Assert.AreEqual (plaintext, roundtrip, "ECB-rt-len");
125 byte[] plaintext = new byte[16];
126 byte[] iv = new byte[16];
128 for (int i=0; i < 16; i++) {
129 plaintext[i] = (byte) (i*16 + i);
132 RijndaelManaged r = new RijndaelManaged();
133 r.Mode = CipherMode.ECB;
134 r.Padding = PaddingMode.Zeros;
136 byte[] key16 = new byte[16];
137 byte[] key24 = new byte[24];
138 byte[] key32 = new byte[32];
140 for (int i=0; i < 32; i++) {
141 if (i < 16) key16[i] = (byte) i;
142 if (i < 24) key24[i] = (byte) i;
147 byte[] exp16 = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
148 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a };
149 byte[] exp24 = { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
150 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 };
151 byte[] exp32 = { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
152 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 };
157 r.CreateEncryptor(key16, iv), r.CreateDecryptor(key16, iv),
165 r.CreateEncryptor(key24, iv), r.CreateDecryptor(key24, iv),
173 r.CreateEncryptor(key32, iv), r.CreateDecryptor(key32, iv),
179 [ExpectedException (typeof (CryptographicException))]
180 public void CreateEncryptor_KeyNull ()
182 ICryptoTransform encryptor = aes.CreateEncryptor (null, aes.IV);
183 byte[] data = new byte[encryptor.InputBlockSize];
184 byte[] encdata = encryptor.TransformFinalBlock (data, 0, data.Length);
186 ICryptoTransform decryptor = aes.CreateDecryptor (aes.Key, aes.IV);
187 byte[] decdata = decryptor.TransformFinalBlock (encdata, 0, encdata.Length);
188 // null key != SymmetricAlgorithm.Key
192 public void CreateEncryptor_IvNull ()
194 ICryptoTransform encryptor = aes.CreateEncryptor (aes.Key, null);
195 byte[] data = new byte[encryptor.InputBlockSize];
196 byte[] encdata = encryptor.TransformFinalBlock (data, 0, data.Length);
198 ICryptoTransform decryptor = aes.CreateDecryptor (aes.Key, aes.IV);
199 byte[] decdata = decryptor.TransformFinalBlock (encdata, 0, encdata.Length);
200 Assert.IsFalse (BitConverter.ToString (data) == BitConverter.ToString (decdata), "Compare");
201 // null iv != SymmetricAlgorithm.IV
205 public void CreateEncryptor_KeyIv ()
207 byte[] originalKey = aes.Key;
208 byte[] originalIV = aes.IV;
210 byte[] key = (byte[]) aes.Key.Clone ();
212 byte[] iv = (byte[]) aes.IV.Clone ();
215 Assert.IsNotNull (aes.CreateEncryptor (key, iv), "CreateEncryptor");
217 Assert.AreEqual (originalKey, aes.Key, "Key");
218 Assert.AreEqual (originalIV, aes.IV, "IV");
219 // SymmetricAlgorithm Key and IV not changed by CreateEncryptor
223 [ExpectedException (typeof (CryptographicException))]
224 [Category ("NotWorking")] // data is bad but no exception is thrown
225 public void CreateDecryptor_KeyNull ()
227 ICryptoTransform encryptor = aes.CreateEncryptor (aes.Key, aes.IV);
228 byte[] data = new byte[encryptor.InputBlockSize];
229 byte[] encdata = encryptor.TransformFinalBlock (data, 0, data.Length);
231 ICryptoTransform decryptor = aes.CreateDecryptor (null, aes.IV);
232 byte[] decdata = decryptor.TransformFinalBlock (encdata, 0, encdata.Length);
233 // null key != SymmetricAlgorithm.Key
237 public void CreateDecryptor_IvNull ()
239 ICryptoTransform encryptor = aes.CreateEncryptor (aes.Key, aes.IV);
240 byte[] data = new byte[encryptor.InputBlockSize];
241 byte[] encdata = encryptor.TransformFinalBlock (data, 0, data.Length);
243 ICryptoTransform decryptor = aes.CreateDecryptor (aes.Key, null);
244 byte[] decdata = decryptor.TransformFinalBlock (encdata, 0, encdata.Length);
245 Assert.IsFalse (BitConverter.ToString (data) == BitConverter.ToString (decdata), "Compare");
246 // null iv != SymmetricAlgorithm.IV
250 public void CreateDecryptor_KeyIv ()
252 byte[] originalKey = aes.Key;
253 byte[] originalIV = aes.IV;
255 byte[] key = (byte[]) aes.Key.Clone ();
257 byte[] iv = (byte[]) aes.IV.Clone ();
260 Assert.IsNotNull (aes.CreateEncryptor (key, iv), "CreateDecryptor");
262 Assert.AreEqual (originalKey, aes.Key, "Key");
263 Assert.AreEqual (originalIV, aes.IV, "IV");
264 // SymmetricAlgorithm Key and IV not changed by CreateDecryptor
267 // Setting the IV is more restrictive than supplying an IV to
268 // CreateEncryptor and CreateDecryptor. See bug #76483
270 private ICryptoTransform CreateEncryptor_IV (int size)
272 byte[] iv = (size == -1) ? null : new byte[size];
273 return aes.CreateEncryptor (aes.Key, iv);
277 public void CreateEncryptor_IV_Null ()
279 int size = (aes.BlockSize >> 3) - 1;
280 CreateEncryptor_IV (-1);
284 [ExpectedException (typeof (CryptographicException))]
285 public void CreateEncryptor_IV_Zero ()
287 int size = (aes.BlockSize >> 3) - 1;
288 CreateEncryptor_IV (0);
292 [ExpectedException (typeof (CryptographicException))]
293 public void CreateEncryptor_IV_TooSmall ()
295 int size = (aes.BlockSize >> 3) - 1;
296 CreateEncryptor_IV (size);
300 public void CreateEncryptor_IV_BlockSize ()
302 int size = (aes.BlockSize >> 3);
303 CreateEncryptor_IV (size);
308 [ExpectedException (typeof (CryptographicException))]
309 // Rijndael is the only implementation that has
310 // this behaviour for IV that are too large
311 [Category ("NotWorking")]
312 public void CreateEncryptor_IV_TooBig ()
314 int size = aes.BlockSize; // 8 times too big
315 CreateEncryptor_IV (size);
319 private ICryptoTransform CreateDecryptor_IV (int size)
321 byte[] iv = (size == -1) ? null : new byte[size];
322 return aes.CreateDecryptor (aes.Key, iv);
326 public void CreateDecryptor_IV_Null ()
328 int size = (aes.BlockSize >> 3) - 1;
329 CreateDecryptor_IV (-1);
333 [ExpectedException (typeof (CryptographicException))]
334 public void CreateDecryptor_IV_Zero ()
336 int size = (aes.BlockSize >> 3) - 1;
337 CreateDecryptor_IV (0);
341 [ExpectedException (typeof (CryptographicException))]
342 public void CreateDecryptor_IV_TooSmall ()
344 int size = (aes.BlockSize >> 3) - 1;
345 CreateDecryptor_IV (size);
349 public void CreateDecryptor_IV_BlockSize ()
351 int size = (aes.BlockSize >> 3);
352 CreateDecryptor_IV (size);
356 [ExpectedException (typeof (CryptographicException))]
357 // Rijndael is the only implementation that has
358 // this behaviour for IV that are too large
359 [Category ("NotWorking")]
360 public void CreateDecryptor_IV_TooBig ()
362 int size = aes.BlockSize; // 8 times too big
363 CreateDecryptor_IV (size);