[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / corlib / Test / System.Security.Cryptography / PaddingModeTest.cs
blob543e4837d0a7b0da600336d3e154632c6e022e95
1 //
2 // PaddingModeTest.cs - NUnit Test Cases for PaddingMode
3 //
4 // Author:
5 // Sebastien Pouliot (sebastien@ximian.com)
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004, 2008 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.
30 using System;
31 using System.Security.Cryptography;
33 using NUnit.Framework;
35 namespace MonoTests.System.Security.Cryptography {
37 [TestFixture]
38 public class PaddingModeTest {
40 private static byte[] key1 = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
41 private static byte[] key2 = { 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01 };
42 private static byte[] key3 = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
44 public void AssertEquals (string msg, byte[] array1, byte[] array2)
46 Assert.AreEqual (array1, array2, msg);
49 protected byte[] CombineKeys (byte[] key1, byte[] key2, byte[] key3)
51 int k1l = key1.Length;
52 int k2l = key2.Length;
53 int k3l = key3.Length;
54 byte[] key = new byte [k1l + k2l + k3l];
55 Array.Copy (key1, 0, key, 0, k1l);
56 Array.Copy (key2, 0, key, k1l, k2l);
57 Array.Copy (key3, 0, key, k1l + k2l, k3l);
58 return key;
61 private byte[] Decrypt (SymmetricAlgorithm algo, PaddingMode padding, byte[] data)
63 algo.IV = new byte [algo.BlockSize >> 3];
64 algo.Mode = CipherMode.CBC;
65 algo.Padding = padding;
66 ICryptoTransform ct = algo.CreateDecryptor ();
67 return ct.TransformFinalBlock (data, 0, data.Length);
70 private byte[] Encrypt (SymmetricAlgorithm algo, PaddingMode padding, byte[] data)
72 algo.IV = new byte [algo.BlockSize >> 3];
73 algo.Mode = CipherMode.CBC;
74 algo.Padding = padding;
75 ICryptoTransform ct = algo.CreateEncryptor ();
76 return ct.TransformFinalBlock (data, 0, data.Length);
79 private byte[] GetData (byte size)
81 byte[] data = new byte [size];
82 for (byte i=0; i < size; i++) {
83 data [i] = i;
85 return data;
88 private TripleDES GetTripleDES ()
90 TripleDES tdes = TripleDES.Create ();
91 tdes.Key = CombineKeys (key1, key2, key3);
92 return tdes;
95 [Test]
96 [ExpectedException (typeof (CryptographicException))]
97 public void TripleDESNone_SmallerThanOneBlockSize ()
99 TripleDES tdes = GetTripleDES ();
100 byte[] data = GetData (7);
101 byte[] encdata = Encrypt (tdes, PaddingMode.None, data);
104 [Test]
105 public void TripleDESNone_ExactlyOneBlockSize ()
107 TripleDES tdes = GetTripleDES ();
108 byte[] data = GetData (8);
109 byte[] encdata = Encrypt (tdes, PaddingMode.None, data);
110 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51", BitConverter.ToString (encdata), "TripleDESNone_ExactlyOneBlockSize_Encrypt");
111 byte[] decdata = Decrypt (tdes, PaddingMode.None, encdata);
112 AssertEquals ("TripleDESNone_ExactlyOneBlockSize_Decrypt", data, decdata);
115 [Test]
116 [ExpectedException (typeof (CryptographicException))]
117 public void TripleDESNone_MoreThanOneBlockSize ()
119 TripleDES tdes = GetTripleDES ();
120 byte[] data = GetData (12);
121 byte[] encdata = Encrypt (tdes, PaddingMode.None, data);
124 [Test]
125 public void TripleDESNone_ExactMultipleBlockSize ()
127 TripleDES tdes = GetTripleDES ();
128 byte[] data = GetData (48);
129 byte[] encdata = Encrypt (tdes, PaddingMode.None, data);
130 // note: encrypted data is truncated to a multiple of block size
131 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51-BF-AB-79-9C-CD-5E-79-40-16-81-0D-6B-40-E6-B2-E9-86-34-8A-9E-5D-56-DA-D1-0C-8C-76-0A-E1-69-A1-0A-B5-B5-7F-FC-5A-D0-6E-6A", BitConverter.ToString (encdata), "TripleDESNone_ExactMultipleBlockSize_Encrypt");
132 byte[] decdata = Decrypt (tdes, PaddingMode.None, encdata);
133 AssertEquals ("TripleDESNone_ExactMultipleBlockSize_Decrypt", GetData (48), decdata);
136 [Test]
137 public void TripleDESPKCS7_SmallerThanOneBlockSize ()
139 TripleDES tdes = GetTripleDES ();
140 byte[] data = GetData (7);
141 byte[] encdata = Encrypt (tdes, PaddingMode.PKCS7, data);
142 Assert.AreEqual ("C6-59-0E-E3-7F-26-92-B0", BitConverter.ToString (encdata), "TripleDESPKCS7_SmallerThanOneBlockSize_Encrypt");
143 byte[] decdata = Decrypt (tdes, PaddingMode.PKCS7, encdata);
144 AssertEquals ("TripleDESPKCS7_SmallerThanOneBlockSize_Decrypt", data, decdata);
147 [Test]
148 public void TripleDESPKCS7_ExactlyOneBlockSize ()
150 TripleDES tdes = GetTripleDES ();
151 byte[] data = GetData (8);
152 byte[] encdata = Encrypt (tdes, PaddingMode.PKCS7, data);
153 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51-C0-60-5B-6A-5C-B7-69-62", BitConverter.ToString (encdata), "TripleDESPKCS7_ExactlyOneBlockSize_Encrypt");
154 byte[] decdata = Decrypt (tdes, PaddingMode.PKCS7, encdata);
155 AssertEquals ("TripleDESPKCS7_ExactlyOneBlockSize_Decrypt", data, decdata);
158 [Test]
159 public void TripleDESPKCS7_MoreThanOneBlockSize ()
161 TripleDES tdes = GetTripleDES ();
162 byte[] data = GetData (12);
163 byte[] encdata = Encrypt (tdes, PaddingMode.PKCS7, data);
164 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51-D9-CB-92-8C-76-89-35-84", BitConverter.ToString (encdata), "TripleDESPKCS7_MoreThanOneBlockSize_Encrypt");
165 byte[] decdata = Decrypt (tdes, PaddingMode.PKCS7, encdata);
166 AssertEquals ("TripleDESPKCS7_MoreThanOneBlockSize_Decrypt", data, decdata);
169 [Test]
170 public void TripleDESPKCS7_ExactMultipleBlockSize ()
172 TripleDES tdes = GetTripleDES ();
173 byte[] data = GetData (48);
174 byte[] encdata = Encrypt (tdes, PaddingMode.PKCS7, data);
175 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51-BF-AB-79-9C-CD-5E-79-40-16-81-0D-6B-40-E6-B2-E9-86-34-8A-9E-5D-56-DA-D1-0C-8C-76-0A-E1-69-A1-0A-B5-B5-7F-FC-5A-D0-6E-6A-73-61-63-1C-58-A2-9C-B3", BitConverter.ToString (encdata), "TripleDESPKCS7_ExactMultipleBlockSize_Encrypt");
176 byte[] decdata = Decrypt (tdes, PaddingMode.PKCS7, encdata);
177 AssertEquals ("TripleDESPKCS7_ExactMultipleBlockSize_Decrypt", data, decdata);
180 [Test]
181 public void TripleDESZeros_SmallerThanOneBlockSize ()
183 TripleDES tdes = GetTripleDES ();
184 byte[] data = GetData (7);
185 byte[] encdata = Encrypt (tdes, PaddingMode.Zeros, data);
186 Assert.AreEqual ("B8-5C-5B-A5-06-0B-7E-C6", BitConverter.ToString (encdata), "TripleDESZeros_SmallerThanOneBlockSize_Encrypt");
187 byte[] decdata = Decrypt (tdes, PaddingMode.Zeros, encdata);
188 Assert.AreEqual ("00-01-02-03-04-05-06-00", BitConverter.ToString (decdata), "TripleDESZeros_SmallerThanOneBlockSize_Decrypt");
191 [Test]
192 public void TripleDESZeros_ExactlyOneBlockSize ()
194 TripleDES tdes = GetTripleDES ();
195 byte[] data = GetData (8);
196 byte[] encdata = Encrypt (tdes, PaddingMode.Zeros, data);
197 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51", BitConverter.ToString (encdata), "TripleDESZeros_ExactlyOneBlockSize_Encrypt");
198 byte[] decdata = Decrypt (tdes, PaddingMode.Zeros, encdata);
199 AssertEquals ("TripleDESZeros_ExactlyOneBlockSize_Decrypt", data, decdata);
202 [Test]
203 public void TripleDESZeros_MoreThanOneBlockSize ()
205 TripleDES tdes = GetTripleDES ();
206 byte[] data = GetData (12);
207 byte[] encdata = Encrypt (tdes, PaddingMode.Zeros, data);
208 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51-6E-75-2E-33-12-09-5D-66", BitConverter.ToString (encdata), "TripleDESZeros_MoreThanOneBlockSize_Encrypt");
209 byte[] decdata = Decrypt (tdes, PaddingMode.Zeros, encdata);
210 Assert.AreEqual ("00-01-02-03-04-05-06-07-08-09-0A-0B-00-00-00-00", BitConverter.ToString (decdata), "TripleDESZeros_MoreThanOneBlockSize_Decrypt");
213 [Test]
214 public void TripleDESZeros_ExactMultipleBlockSize ()
216 TripleDES tdes = GetTripleDES ();
217 byte[] data = GetData (48);
218 byte[] encdata = Encrypt (tdes, PaddingMode.Zeros, data);
219 Assert.AreEqual ("23-61-AC-E6-C5-17-10-51-BF-AB-79-9C-CD-5E-79-40-16-81-0D-6B-40-E6-B2-E9-86-34-8A-9E-5D-56-DA-D1-0C-8C-76-0A-E1-69-A1-0A-B5-B5-7F-FC-5A-D0-6E-6A", BitConverter.ToString (encdata), "TripleDESZeros_ExactMultipleBlockSize_Encrypt");
220 byte[] decdata = Decrypt (tdes, PaddingMode.Zeros, encdata);
221 AssertEquals ("TripleDESZeros_ExactMultipleBlockSize_Decrypt", GetData (48), decdata);
224 private Rijndael GetAES ()
226 Rijndael aes = Rijndael.Create ();
227 aes.Key = CombineKeys (key1, key2, key3);
228 return aes;
231 [Test]
232 [ExpectedException (typeof (CryptographicException))]
233 public void RijndaelNone_SmallerThanOneBlockSize ()
235 Rijndael aes = GetAES ();
236 byte[] data = GetData (8);
237 byte[] encdata = Encrypt (aes, PaddingMode.None, data);
240 [Test]
241 public void RijndaelNone_ExactlyOneBlockSize ()
243 Rijndael aes = GetAES ();
244 byte[] data = GetData (16);
245 byte[] encdata = Encrypt (aes, PaddingMode.None, data);
246 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB", BitConverter.ToString (encdata), "RijndaelNone_ExactlyOneBlockSize_Encrypt");
247 byte[] decdata = Decrypt (aes, PaddingMode.None, encdata);
248 AssertEquals ("RijndaelNone_ExactlyOneBlockSize_Decrypt", data, decdata);
251 [Test]
252 [ExpectedException (typeof (CryptographicException))]
253 public void RijndaelNone_MoreThanOneBlockSize ()
255 Rijndael aes = GetAES ();
256 byte[] data = GetData (20);
257 byte[] encdata = Encrypt (aes, PaddingMode.None, data);
260 [Test]
261 public void RijndaelNone_ExactMultipleBlockSize ()
263 Rijndael aes = GetAES ();
264 byte[] data = GetData (48);
265 byte[] encdata = Encrypt (aes, PaddingMode.None, data);
266 // note: encrypted data is truncated to a multiple of block size
267 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB-E1-27-3E-21-5A-BE-D5-12-F4-AF-06-8D-0A-BD-02-64-02-CB-FF-D7-32-19-5E-69-3C-54-C2-8C-A1-D7-72-FF", BitConverter.ToString (encdata), "RijndaelNone_ExactMultipleBlockSize_Encrypt");
268 byte[] decdata = Decrypt (aes, PaddingMode.None, encdata);
269 AssertEquals ("RijndaelNone_ExactMultipleBlockSize_Decrypt", GetData (48), decdata);
272 [Test]
273 public void RijndaelPKCS7_SmallerThanOneBlockSize ()
275 Rijndael aes = GetAES ();
276 byte[] data = GetData (8);
277 byte[] encdata = Encrypt (aes, PaddingMode.PKCS7, data);
278 Assert.AreEqual ("AB-E0-20-5E-BC-28-A0-B7-A7-56-A3-BF-13-55-13-7E", BitConverter.ToString (encdata), "RijndaelPKCS7_SmallerThanOneBlockSize_Encrypt");
279 byte[] decdata = Decrypt (aes, PaddingMode.PKCS7, encdata);
280 AssertEquals ("RijndaelPKCS7_SmallerThanOneBlockSize_Decrypt", data, decdata);
283 [Test]
284 public void RijndaelPKCS7_ExactlyOneBlockSize ()
286 Rijndael aes = GetAES ();
287 byte[] data = GetData (16);
288 byte[] encdata = Encrypt (aes, PaddingMode.PKCS7, data);
289 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB-60-CE-9F-E0-72-3B-D6-D1-A5-F8-33-D8-25-31-7F-D4", BitConverter.ToString (encdata), "RijndaelPKCS7_ExactlyOneBlockSize_Encrypt");
290 byte[] decdata = Decrypt (aes, PaddingMode.PKCS7, encdata);
291 AssertEquals ("RijndaelPKCS7_ExactlyOneBlockSize_Decrypt", data, decdata);
294 [Test]
295 public void RijndaelPKCS7_MoreThanOneBlockSize ()
297 Rijndael aes = GetAES ();
298 byte[] data = GetData (20);
299 byte[] encdata = Encrypt (aes, PaddingMode.PKCS7, data);
300 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB-06-3F-D3-51-8D-55-E9-2F-02-4A-4E-F2-91-55-31-83", BitConverter.ToString (encdata), "RijndaelPKCS7_MoreThanOneBlockSize_Encrypt");
301 byte[] decdata = Decrypt (aes, PaddingMode.PKCS7, encdata);
302 AssertEquals ("RijndaelPKCS7_MoreThanOneBlockSize_Decrypt", data, decdata);
305 [Test]
306 public void RijndaelPKCS7_ExactMultipleBlockSize ()
308 Rijndael aes = GetAES ();
309 byte[] data = GetData (48);
310 byte[] encdata = Encrypt (aes, PaddingMode.PKCS7, data);
311 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB-E1-27-3E-21-5A-BE-D5-12-F4-AF-06-8D-0A-BD-02-64-02-CB-FF-D7-32-19-5E-69-3C-54-C2-8C-A1-D7-72-FF-37-42-81-21-47-A7-E0-AA-64-A7-8B-65-25-95-AA-54", BitConverter.ToString (encdata), "RijndaelPKCS7_ExactMultipleBlockSize_Encrypt");
312 byte[] decdata = Decrypt (aes, PaddingMode.PKCS7, encdata);
313 AssertEquals ("RijndaelPKCS7_ExactMultipleBlockSize_Decrypt", data, decdata);
316 [Test]
317 public void RijndaelZeros_SmallerThanOneBlockSize ()
319 Rijndael aes = GetAES ();
320 byte[] data = GetData (8);
321 byte[] encdata = Encrypt (aes, PaddingMode.Zeros, data);
322 Assert.AreEqual ("DD-BE-D7-CE-E2-DD-5C-A3-3E-44-A1-76-00-E5-5B-5D", BitConverter.ToString (encdata), "RijndaelZeros_SmallerThanOneBlockSize_Encrypt");
323 byte[] decdata = Decrypt (aes, PaddingMode.Zeros, encdata);
324 Assert.AreEqual ("00-01-02-03-04-05-06-07-00-00-00-00-00-00-00-00", BitConverter.ToString (decdata), "RijndaelZeros_SmallerThanOneBlockSize_Decrypt");
327 [Test]
328 public void RijndaelZeros_ExactlyOneBlockSize ()
330 Rijndael aes = GetAES ();
331 byte[] data = GetData (16);
332 byte[] encdata = Encrypt (aes, PaddingMode.Zeros, data);
333 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB", BitConverter.ToString (encdata), "RijndaelZeros_ExactlyOneBlockSize_Encrypt");
334 byte[] decdata = Decrypt (aes, PaddingMode.Zeros, encdata);
335 AssertEquals ("RijndaelZeros_ExactlyOneBlockSize_Decrypt", data, decdata);
338 [Test]
339 public void RijndaelZeros_MoreThanOneBlockSize ()
341 Rijndael aes = GetAES ();
342 byte[] data = GetData (20);
343 byte[] encdata = Encrypt (aes, PaddingMode.Zeros, data);
344 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB-04-6C-F7-A5-DE-FF-B4-30-29-7A-0E-04-3B-D4-B8-F2", BitConverter.ToString (encdata), "RijndaelZeros_MoreThanOneBlockSize_Encrypt");
345 byte[] decdata = Decrypt (aes, PaddingMode.Zeros, encdata);
346 Assert.AreEqual ("00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-11-12-13-00-00-00-00-00-00-00-00-00-00-00-00", BitConverter.ToString (decdata), "RijndaelZeros_MoreThanOneBlockSize_Decrypt");
349 [Test]
350 public void RijndaelZeros_ExactMultipleBlockSize ()
352 Rijndael aes = GetAES ();
353 byte[] data = GetData (48);
354 byte[] encdata = Encrypt (aes, PaddingMode.Zeros, data);
355 Assert.AreEqual ("79-42-36-2F-D6-DB-F1-0C-87-99-58-06-D5-F6-B0-BB-E1-27-3E-21-5A-BE-D5-12-F4-AF-06-8D-0A-BD-02-64-02-CB-FF-D7-32-19-5E-69-3C-54-C2-8C-A1-D7-72-FF", BitConverter.ToString (encdata), "RijndaelZeros_ExactMultipleBlockSize_Encrypt");
356 byte[] decdata = Decrypt (aes, PaddingMode.Zeros, encdata);
357 AssertEquals ("RijndaelZeros_ExactMultipleBlockSize_Decrypt", GetData (48), decdata);
360 // Enum tests
362 [Test]
363 public void PaddingModeEnum ()
365 Assert.AreEqual (4, (int)PaddingMode.ANSIX923, "ANSIX923");
366 Assert.AreEqual (5, (int)PaddingMode.ISO10126, "ISO10126");
367 Assert.AreEqual (1, (int)PaddingMode.None, "None");
368 Assert.AreEqual (2, (int)PaddingMode.PKCS7, "PKCS7");
369 Assert.AreEqual (3, (int)PaddingMode.Zeros, "Zeros");
372 // SymmetricAlgorithm tests
374 private byte[] GetKey (SymmetricAlgorithm sa)
376 byte[] key = new byte [sa.KeySize >> 3];
377 // no weak key this way (DES, TripleDES)
378 for (byte i=0; i < key.Length; i++)
379 key [i] = i;
380 return key;
383 private byte[] GetIV (SymmetricAlgorithm sa)
385 return new byte [sa.BlockSize >> 3];
388 private ICryptoTransform GetEncryptor (SymmetricAlgorithm sa, PaddingMode mode)
390 sa.Mode = CipherMode.ECB; // basic (no) mode
391 sa.Padding = mode;
392 return sa.CreateEncryptor (GetKey (sa), GetIV (sa));
395 private ICryptoTransform GetDecryptor (SymmetricAlgorithm sa, PaddingMode mode)
397 sa.Mode = CipherMode.ECB; // basic (no) mode
398 sa.Padding = mode;
399 return sa.CreateDecryptor (GetKey (sa), GetIV (sa));
402 // the best way to verify padding is to:
403 // a. encrypt data larger than one block with a padding mode "X"
404 // b. decrypt the data with padding mode "None"
405 // c. compare the last (padding) bytes with the expected padding
406 private void ANSIX923_Full (SymmetricAlgorithm sa)
408 int bs = (sa.BlockSize >> 3);
409 // one full block
410 byte[] data = new byte [bs]; // in bytes
411 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.ANSIX923);
412 byte[] encdata = enc.TransformFinalBlock (data, 0, data.Length);
413 // one block of padding is added
414 Assert.AreEqual (data.Length * 2, encdata.Length, "one more block added");
416 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
417 byte[] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
418 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
420 int pd = decdata.Length - data.Length;
421 // now validate padding - ANSI X.923 is all 0 except last byte (length)
422 for (int i=0; i < bs - 1; i++)
423 Assert.AreEqual (0x00, decdata [decdata.Length - pd + i], i.ToString ());
424 Assert.AreEqual (pd, decdata [decdata.Length - 1], "last byte");
427 private void ANSIX923_Partial (SymmetricAlgorithm sa)
429 int bs = (sa.BlockSize >> 3);
430 // one and an half block
431 byte[] data = new byte [bs + (bs >> 1)]; // in bytes
432 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.ANSIX923);
433 byte[] encdata = enc.TransformFinalBlock (data, 0, data.Length);
434 // one block of padding is added
435 Assert.AreEqual (bs * 2, encdata.Length, "one more block added");
437 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
438 byte[] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
439 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
441 int pd = decdata.Length - data.Length;
442 // now validate padding - ANSI X.923 is all 0 except last byte (length)
443 for (int i = 0; i < pd - 1; i++)
444 Assert.AreEqual (0x00, decdata [decdata.Length - pd + i], i.ToString ());
445 Assert.AreEqual (pd, decdata [decdata.Length - 1], "last byte");
448 private void ISO10126_Full (SymmetricAlgorithm sa)
450 int bs = (sa.BlockSize >> 3);
451 // one full block
452 byte [] data = new byte [bs]; // in bytes
453 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.ISO10126);
454 byte [] encdata = enc.TransformFinalBlock (data, 0, data.Length);
455 // one block of padding is added
456 Assert.AreEqual (data.Length * 2, encdata.Length, "one more block added");
458 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
459 byte [] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
460 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
462 int pd = decdata.Length - data.Length;
463 // now validate padding - ISO10126 is all random except last byte (length)
464 Assert.AreEqual (pd, decdata [decdata.Length - 1], "last byte");
467 private void ISO10126_Partial (SymmetricAlgorithm sa)
469 int bs = (sa.BlockSize >> 3);
470 // one and an half block
471 byte [] data = new byte [bs + (bs >> 1)]; // in bytes
472 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.ISO10126);
473 byte [] encdata = enc.TransformFinalBlock (data, 0, data.Length);
474 // one block of padding is added
475 Assert.AreEqual (bs * 2, encdata.Length, "one more block added");
477 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
478 byte [] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
479 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
481 int pd = decdata.Length - data.Length;
482 // now validate padding - ISO10126 is all random except last byte (length)
483 Assert.AreEqual (pd, decdata [decdata.Length - 1], "last byte");
485 private void PKCS7_Full (SymmetricAlgorithm sa)
487 int bs = (sa.BlockSize >> 3);
488 // one full block
489 byte[] data = new byte [bs]; // in bytes
490 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.PKCS7);
491 byte[] encdata = enc.TransformFinalBlock (data, 0, data.Length);
492 // one block of padding is added
493 Assert.AreEqual (data.Length * 2, encdata.Length, "one more block added");
495 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
496 byte[] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
497 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
499 int pd = decdata.Length - data.Length;
500 // now validate padding - PKCS7 is all padding char
501 for (int i = 0; i < bs; i++)
502 Assert.AreEqual (pd, decdata [decdata.Length - pd + i], i.ToString ());
505 private void PKCS7_Partial (SymmetricAlgorithm sa)
507 int bs = (sa.BlockSize >> 3);
508 // one and an half block
509 byte[] data = new byte[bs + (bs >> 1)]; // in bytes
510 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.PKCS7);
511 byte[] encdata = enc.TransformFinalBlock (data, 0, data.Length);
512 // one block of padding is added
513 Assert.AreEqual (bs * 2, encdata.Length, "one more block added");
515 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
516 byte[] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
517 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
519 int pd = decdata.Length - data.Length;
520 // now validate padding - PKCS7 is all padding char
521 for (int i = 0; i < pd; i++)
522 Assert.AreEqual (pd, decdata [decdata.Length - pd + i], i.ToString ());
525 private void Zeros_Full (SymmetricAlgorithm sa)
527 int bs = (sa.BlockSize >> 3);
528 // one full block
529 byte [] data = new byte [bs]; // in bytes
530 for (int i = 0; i < data.Length; i++)
531 data [i] = 0xFF;
533 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.Zeros);
534 byte [] encdata = enc.TransformFinalBlock (data, 0, data.Length);
535 // NO extra block is used for zero padding
536 Assert.AreEqual (data.Length, encdata.Length, "no extra block added");
538 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
539 byte [] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
540 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
542 // now validate absence of padding
543 Assert.AreEqual (0xFF, decdata [decdata.Length - 1], "no padding");
546 private void Zeros_Partial (SymmetricAlgorithm sa)
548 int bs = (sa.BlockSize >> 3);
549 // one and an half block
550 byte [] data = new byte [bs + (bs >> 1)]; // in bytes
551 for (int i=0; i < data.Length; i++)
552 data [i] = 0xFF;
554 ICryptoTransform enc = GetEncryptor (sa, PaddingMode.Zeros);
555 byte [] encdata = enc.TransformFinalBlock (data, 0, data.Length);
556 // one block of padding is added
557 Assert.AreEqual (bs * 2, encdata.Length, "one more block added");
559 ICryptoTransform dec = GetDecryptor (sa, PaddingMode.None);
560 byte [] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
561 Assert.AreEqual (encdata.Length, decdata.Length, "no unpadding");
563 int pd = decdata.Length - data.Length;
564 // now validate padding - Zeros is all 0x00 char
565 for (int i = 0; i < pd; i++)
566 Assert.AreEqual (0x00, decdata [decdata.Length - pd + i], i.ToString ());
568 // ANSI X.923
570 [Test]
571 public void DES_ANSIX923_Full ()
573 ANSIX923_Full (DES.Create ());
576 [Test]
577 public void DES_ANSIX923_Partial ()
579 ANSIX923_Partial (DES.Create ());
582 [Test]
583 public void RC2_ANSIX923_Full ()
585 ANSIX923_Full (RC2.Create ());
588 [Test]
589 public void RC2_ANSIX923_Partial ()
591 ANSIX923_Partial (RC2.Create ());
594 [Test]
595 public void Rijndael_ANSIX923_Full ()
597 ANSIX923_Full (Rijndael.Create ());
600 [Test]
601 public void Rijndael_ANSIX923_Partial ()
603 ANSIX923_Partial (Rijndael.Create ());
606 [Test]
607 public void TripleDES_ANSIX923_Full ()
609 ANSIX923_Full (TripleDES.Create ());
612 [Test]
613 public void TripleDES_ANSIX923_Partial ()
615 ANSIX923_Partial (TripleDES.Create ());
618 // ISO 10126
620 [Test]
621 public void DES_ISO10126_Full ()
623 ISO10126_Full (DES.Create ());
626 [Test]
627 public void DES_ISO10126_Partial ()
629 ISO10126_Partial (DES.Create ());
632 [Test]
633 public void RC2_ISO10126_Full ()
635 ISO10126_Full (RC2.Create ());
638 [Test]
639 public void RC2_ISO10126_Partial ()
641 ISO10126_Partial (RC2.Create ());
644 [Test]
645 public void Rijndael_ISO10126_Full ()
647 ISO10126_Full (Rijndael.Create ());
650 [Test]
651 public void Rijndael_ISO10126_Partial ()
653 ISO10126_Partial (Rijndael.Create ());
656 [Test]
657 public void TripleDES_ISO10126_Full ()
659 ISO10126_Full (TripleDES.Create ());
662 [Test]
663 public void TripleDES_ISO10126_Partial ()
665 ISO10126_Partial (TripleDES.Create ());
667 // PKCS #7
669 [Test]
670 public void DES_PKCS7_Full ()
672 PKCS7_Full (DES.Create ());
675 [Test]
676 public void DES_PKCS7_Partial ()
678 PKCS7_Partial (DES.Create ());
681 [Test]
682 public void RC2_PKCS7_Full ()
684 PKCS7_Full (RC2.Create ());
687 [Test]
688 public void RC2_PKCS7_Partial ()
690 PKCS7_Partial (RC2.Create ());
693 [Test]
694 public void Rijndael_PKCS7_Full ()
696 PKCS7_Full (Rijndael.Create ());
699 [Test]
700 public void Rijndael_PKCS7_Partial ()
702 PKCS7_Partial (Rijndael.Create ());
705 [Test]
706 public void TripleDES_PKCS7_Full ()
708 PKCS7_Full (TripleDES.Create ());
711 [Test]
712 public void TripleDES_PKCS7_Partial ()
714 PKCS7_Partial (TripleDES.Create ());
717 // Zeros
719 [Test]
720 public void DES_Zeros_Full ()
722 Zeros_Full (DES.Create ());
725 [Test]
726 public void DES_Zeros_Partial ()
728 Zeros_Partial (DES.Create ());
731 [Test]
732 public void RC2_Zeros_Full ()
734 Zeros_Full (RC2.Create ());
737 [Test]
738 public void RC2_Zeros_Partial ()
740 Zeros_Partial (RC2.Create ());
743 [Test]
744 public void Rijndael_Zeros_Full ()
746 Zeros_Full (Rijndael.Create ());
749 [Test]
750 public void Rijndael_Zeros_Partial ()
752 Zeros_Partial (Rijndael.Create ());
755 [Test]
756 public void TripleDES_Zeros_Full ()
758 Zeros_Full (TripleDES.Create ());
761 [Test]
762 public void TripleDES_Zeros_Partial ()
764 Zeros_Partial (TripleDES.Create ());
767 // Padding mismatches
769 // the best way to test bad padding is to:
770 // a. encrypt data larger than one block with a padding mode "X"
771 // b. decrypt the data with padding mode "Y" (different with Y)
772 // c. check if the "bad" padding was removed correctly
774 // returns (bitmask)
775 // 1 - length difference
776 // 2 - original data lost
777 // 4 - CryptographicException thrown while decryption
778 private int Mismatch (PaddingMode encrypt, PaddingMode decrypt)
780 SymmetricAlgorithm sa = SymmetricAlgorithm.Create ();
781 int bs = (sa.BlockSize >> 3);
782 // one full block
783 byte [] data = new byte [bs]; // in bytes
784 ICryptoTransform enc = GetEncryptor (sa, encrypt);
785 byte [] encdata = enc.TransformFinalBlock (data, 0, data.Length);
787 int result = 0;
788 try {
789 ICryptoTransform dec = GetDecryptor (sa, decrypt);
790 byte [] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
792 if (data.Length != decdata.Length)
793 result += 1;
795 for (int i=0; i < data.Length; i++) {
796 if (data [i] != decdata [i]) {
797 result += 2;
798 break;
802 catch (CryptographicException) {
803 result += 4;
805 return result;
807 [Test]
808 public void ANSIX923_ISO10126 ()
810 Assert.AreEqual (0, Mismatch (PaddingMode.ANSIX923, PaddingMode.ISO10126));
813 [Test]
814 public void ANSIX923_None ()
816 Assert.AreEqual (1, Mismatch (PaddingMode.ANSIX923, PaddingMode.None));
819 [Test]
820 public void ANSIX923_PKCS7 ()
822 Assert.AreEqual (4, Mismatch (PaddingMode.ANSIX923, PaddingMode.PKCS7));
825 [Test]
826 public void ANSIX923_Zeros ()
828 Assert.AreEqual (1, Mismatch (PaddingMode.ANSIX923, PaddingMode.Zeros));
831 [Test]
832 public void ISO10126_ANSIX923 ()
834 Assert.AreEqual (4, Mismatch (PaddingMode.ISO10126, PaddingMode.ANSIX923));
837 [Test]
838 public void ISO10126_None ()
840 Assert.AreEqual (1, Mismatch (PaddingMode.ISO10126, PaddingMode.None));
843 [Test]
844 public void ISO10126_PKCS7 ()
846 Assert.AreEqual (4, Mismatch (PaddingMode.ISO10126, PaddingMode.PKCS7));
849 [Test]
850 public void ISO10126_Zeros ()
852 Assert.AreEqual (1, Mismatch (PaddingMode.ISO10126, PaddingMode.Zeros));
855 [Test]
856 public void None_ANSIX923 ()
858 Assert.AreEqual (4, Mismatch (PaddingMode.None, PaddingMode.ANSIX923));
861 [Test]
862 public void None_ISO10126 ()
864 Assert.AreEqual (4, Mismatch (PaddingMode.None, PaddingMode.ISO10126));
866 [Test]
867 public void None_PKCS7 ()
869 Assert.AreEqual (4, Mismatch (PaddingMode.None, PaddingMode.PKCS7));
872 [Test]
873 public void None_Zeros ()
875 Assert.AreEqual (0, Mismatch (PaddingMode.None, PaddingMode.Zeros));
877 [Test]
878 public void PKCS7_ANSIX923 ()
880 Assert.AreEqual (4, Mismatch (PaddingMode.PKCS7, PaddingMode.ANSIX923));
883 [Test]
884 public void PKCS7_ISO10126 ()
886 Assert.AreEqual (0, Mismatch (PaddingMode.PKCS7, PaddingMode.ISO10126));
888 [Test]
889 public void PKCS7_None ()
891 Assert.AreEqual (1, Mismatch (PaddingMode.PKCS7, PaddingMode.None));
894 [Test]
895 public void PKCS7_Zeros ()
897 Assert.AreEqual (1, Mismatch (PaddingMode.PKCS7, PaddingMode.Zeros));
899 [Test]
900 public void Zeros_ANSIX923 ()
902 Assert.AreEqual (4, Mismatch (PaddingMode.Zeros, PaddingMode.ANSIX923));
905 [Test]
906 public void Zeros_ISO10126 ()
908 Assert.AreEqual (4, Mismatch (PaddingMode.Zeros, PaddingMode.ISO10126));
910 [Test]
911 public void Zeros_None ()
913 Assert.AreEqual (0, Mismatch (PaddingMode.Zeros, PaddingMode.None));
916 [Test]
917 public void Zeros_PKCS7 ()
919 Assert.AreEqual (4, Mismatch (PaddingMode.Zeros, PaddingMode.PKCS7));
922 // MACTripleDES tests
923 private string MAC (PaddingMode padding, int length)
925 byte[] key = new byte [24] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
926 MACTripleDES mac = new MACTripleDES (key);
927 mac.Padding = padding;
928 byte[] data = new byte [length];
929 byte[] hash = mac.TransformFinalBlock (data, 0, data.Length);
930 string result = BitConverter.ToString (mac.Hash);
931 return result;
934 // Note: TripleDES block size is 8 bytes
936 [Test]
937 public void MACTripleDES_ANSIX923 ()
939 Assert.AreEqual ("F6-61-3E-C8-E4-A4-D1-A8", MAC (PaddingMode.ANSIX923, 8), "Full");
940 Assert.AreEqual ("62-C3-78-B0-27-FC-EB-E0", MAC (PaddingMode.ANSIX923, 4), "Partial");
943 [Test]
944 public void MACTripleDES_ISO10126 ()
946 // ISO 10126 use random in it's padding so we can't use it to get "repeatable" results
947 // (i.e. each call will get different result). This isn't a padding to use for MACing!!!
948 Assert.AreEqual (23, MAC (PaddingMode.ISO10126, 8).Length, "Full");
949 Assert.AreEqual (23, MAC (PaddingMode.ISO10126, 4).Length, "Partial");
952 [Test]
953 public void MACTripleDES_None ()
955 Assert.AreEqual ("46-34-5C-8E-EB-DC-74-5C", MAC (PaddingMode.None, 8), "Full");
958 [Test]
959 [ExpectedException (typeof (CryptographicException))]
960 public void MACTripleDES_None_Partial ()
962 // Illegal - must be a multiple of block size
963 MAC (PaddingMode.None, 4);
966 [Test]
967 public void MACTripleDES_PKCS7 ()
969 Assert.AreEqual ("17-71-9F-D5-0B-EF-1D-07", MAC (PaddingMode.PKCS7, 8), "Full");
970 Assert.AreEqual ("5B-3A-13-6F-3F-6F-13-22", MAC (PaddingMode.PKCS7, 4), "Partial");
973 [Test]
974 public void MACTripleDES_Zeros ()
976 Assert.AreEqual ("46-34-5C-8E-EB-DC-74-5C", MAC (PaddingMode.Zeros, 8));
977 Assert.AreEqual ("46-34-5C-8E-EB-DC-74-5C", MAC (PaddingMode.Zeros, 4));
980 // https://bugzilla.novell.com/show_bug.cgi?id=366623
982 [Test]
983 public void ANSIX923_366623 ()
985 TripleDES algo = GetTripleDES ();
986 algo.IV = new byte [algo.BlockSize >> 3];
987 algo.Mode = CipherMode.ECB;
988 algo.Padding = PaddingMode.ANSIX923;
990 ICryptoTransform enc = algo.CreateEncryptor ();
991 byte[] data = new byte [2] { 0xff, 0xff };
992 byte[] encdata = enc.TransformFinalBlock (data, 0, 2);
993 ICryptoTransform dec = algo.CreateDecryptor ();
994 byte[] decdata = dec.TransformFinalBlock (encdata, 0, encdata.Length);
995 Assert.AreEqual (data, decdata);