2 // PaddingModeTest.cs - NUnit Test Cases for PaddingMode
5 // Sebastien Pouliot (sebastien@ximian.com)
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
31 using System
.Security
.Cryptography
;
33 using NUnit
.Framework
;
35 namespace MonoTests
.System
.Security
.Cryptography
{
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 AllTests
.AssertEquals (msg
, array1
, array2
);
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
);
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
++) {
88 private TripleDES
GetTripleDES ()
90 TripleDES tdes
= TripleDES
.Create ();
91 tdes
.Key
= CombineKeys (key1
, key2
, key3
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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");
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
);
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");
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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");
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
);
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");
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
);
363 public void PaddingModeEnum ()
366 Assert
.AreEqual (4, (int)PaddingMode
.ANSIX923
, "ANSIX923");
367 Assert
.AreEqual (5, (int)PaddingMode
.ISO10126
, "ISO10126");
369 Assert
.AreEqual (1, (int)PaddingMode
.None
, "None");
370 Assert
.AreEqual (2, (int)PaddingMode
.PKCS7
, "PKCS7");
371 Assert
.AreEqual (3, (int)PaddingMode
.Zeros
, "Zeros");
374 // SymmetricAlgorithm tests
376 private byte[] GetKey (SymmetricAlgorithm sa
)
378 byte[] key
= new byte [sa
.KeySize
>> 3];
379 // no weak key this way (DES, TripleDES)
380 for (byte i
=0; i
< key
.Length
; i
++)
385 private byte[] GetIV (SymmetricAlgorithm sa
)
387 return new byte [sa
.BlockSize
>> 3];
390 private ICryptoTransform
GetEncryptor (SymmetricAlgorithm sa
, PaddingMode mode
)
392 sa
.Mode
= CipherMode
.ECB
; // basic (no) mode
394 return sa
.CreateEncryptor (GetKey (sa
), GetIV (sa
));
397 private ICryptoTransform
GetDecryptor (SymmetricAlgorithm sa
, PaddingMode mode
)
399 sa
.Mode
= CipherMode
.ECB
; // basic (no) mode
401 return sa
.CreateDecryptor (GetKey (sa
), GetIV (sa
));
404 // the best way to verify padding is to:
405 // a. encrypt data larger than one block with a padding mode "X"
406 // b. decrypt the data with padding mode "None"
407 // c. compare the last (padding) bytes with the expected padding
409 private void ANSIX923_Full (SymmetricAlgorithm sa
)
411 int bs
= (sa
.BlockSize
>> 3);
413 byte[] data
= new byte [bs
]; // in bytes
414 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.ANSIX923
);
415 byte[] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
416 // one block of padding is added
417 Assert
.AreEqual (data
.Length
* 2, encdata
.Length
, "one more block added");
419 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
420 byte[] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
421 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
423 int pd
= decdata
.Length
- data
.Length
;
424 // now validate padding - ANSI X.923 is all 0 except last byte (length)
425 for (int i
=0; i
< bs
- 1; i
++)
426 Assert
.AreEqual (0x00, decdata
[decdata
.Length
- pd
+ i
], i
.ToString ());
427 Assert
.AreEqual (pd
, decdata
[decdata
.Length
- 1], "last byte");
430 private void ANSIX923_Partial (SymmetricAlgorithm sa
)
432 int bs
= (sa
.BlockSize
>> 3);
433 // one and an half block
434 byte[] data
= new byte [bs
+ (bs
>> 1)]; // in bytes
435 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.ANSIX923
);
436 byte[] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
437 // one block of padding is added
438 Assert
.AreEqual (bs
* 2, encdata
.Length
, "one more block added");
440 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
441 byte[] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
442 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
444 int pd
= decdata
.Length
- data
.Length
;
445 // now validate padding - ANSI X.923 is all 0 except last byte (length)
446 for (int i
= 0; i
< pd
- 1; i
++)
447 Assert
.AreEqual (0x00, decdata
[decdata
.Length
- pd
+ i
], i
.ToString ());
448 Assert
.AreEqual (pd
, decdata
[decdata
.Length
- 1], "last byte");
451 private void ISO10126_Full (SymmetricAlgorithm sa
)
453 int bs
= (sa
.BlockSize
>> 3);
455 byte [] data
= new byte [bs
]; // in bytes
456 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.ISO10126
);
457 byte [] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
458 // one block of padding is added
459 Assert
.AreEqual (data
.Length
* 2, encdata
.Length
, "one more block added");
461 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
462 byte [] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
463 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
465 int pd
= decdata
.Length
- data
.Length
;
466 // now validate padding - ISO10126 is all random except last byte (length)
467 Assert
.AreEqual (pd
, decdata
[decdata
.Length
- 1], "last byte");
470 private void ISO10126_Partial (SymmetricAlgorithm sa
)
472 int bs
= (sa
.BlockSize
>> 3);
473 // one and an half block
474 byte [] data
= new byte [bs
+ (bs
>> 1)]; // in bytes
475 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.ISO10126
);
476 byte [] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
477 // one block of padding is added
478 Assert
.AreEqual (bs
* 2, encdata
.Length
, "one more block added");
480 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
481 byte [] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
482 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
484 int pd
= decdata
.Length
- data
.Length
;
485 // now validate padding - ISO10126 is all random except last byte (length)
486 Assert
.AreEqual (pd
, decdata
[decdata
.Length
- 1], "last byte");
489 private void PKCS7_Full (SymmetricAlgorithm sa
)
491 int bs
= (sa
.BlockSize
>> 3);
493 byte[] data
= new byte [bs
]; // in bytes
494 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.PKCS7
);
495 byte[] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
496 // one block of padding is added
497 Assert
.AreEqual (data
.Length
* 2, encdata
.Length
, "one more block added");
499 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
500 byte[] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
501 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
503 int pd
= decdata
.Length
- data
.Length
;
504 // now validate padding - PKCS7 is all padding char
505 for (int i
= 0; i
< bs
; i
++)
506 Assert
.AreEqual (pd
, decdata
[decdata
.Length
- pd
+ i
], i
.ToString ());
509 private void PKCS7_Partial (SymmetricAlgorithm sa
)
511 int bs
= (sa
.BlockSize
>> 3);
512 // one and an half block
513 byte[] data
= new byte[bs
+ (bs
>> 1)]; // in bytes
514 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.PKCS7
);
515 byte[] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
516 // one block of padding is added
517 Assert
.AreEqual (bs
* 2, encdata
.Length
, "one more block added");
519 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
520 byte[] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
521 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
523 int pd
= decdata
.Length
- data
.Length
;
524 // now validate padding - PKCS7 is all padding char
525 for (int i
= 0; i
< pd
; i
++)
526 Assert
.AreEqual (pd
, decdata
[decdata
.Length
- pd
+ i
], i
.ToString ());
529 private void Zeros_Full (SymmetricAlgorithm sa
)
531 int bs
= (sa
.BlockSize
>> 3);
533 byte [] data
= new byte [bs
]; // in bytes
534 for (int i
= 0; i
< data
.Length
; i
++)
537 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.Zeros
);
538 byte [] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
539 // NO extra block is used for zero padding
540 Assert
.AreEqual (data
.Length
, encdata
.Length
, "no extra block added");
542 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
543 byte [] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
544 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
546 // now validate absence of padding
547 Assert
.AreEqual (0xFF, decdata
[decdata
.Length
- 1], "no padding");
550 private void Zeros_Partial (SymmetricAlgorithm sa
)
552 int bs
= (sa
.BlockSize
>> 3);
553 // one and an half block
554 byte [] data
= new byte [bs
+ (bs
>> 1)]; // in bytes
555 for (int i
=0; i
< data
.Length
; i
++)
558 ICryptoTransform enc
= GetEncryptor (sa
, PaddingMode
.Zeros
);
559 byte [] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
560 // one block of padding is added
561 Assert
.AreEqual (bs
* 2, encdata
.Length
, "one more block added");
563 ICryptoTransform dec
= GetDecryptor (sa
, PaddingMode
.None
);
564 byte [] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
565 Assert
.AreEqual (encdata
.Length
, decdata
.Length
, "no unpadding");
567 int pd
= decdata
.Length
- data
.Length
;
568 // now validate padding - Zeros is all 0x00 char
569 for (int i
= 0; i
< pd
; i
++)
570 Assert
.AreEqual (0x00, decdata
[decdata
.Length
- pd
+ i
], i
.ToString ());
576 public void DES_ANSIX923_Full ()
578 ANSIX923_Full (DES
.Create ());
582 public void DES_ANSIX923_Partial ()
584 ANSIX923_Partial (DES
.Create ());
588 public void RC2_ANSIX923_Full ()
590 ANSIX923_Full (RC2
.Create ());
594 public void RC2_ANSIX923_Partial ()
596 ANSIX923_Partial (RC2
.Create ());
600 public void Rijndael_ANSIX923_Full ()
602 ANSIX923_Full (Rijndael
.Create ());
606 public void Rijndael_ANSIX923_Partial ()
608 ANSIX923_Partial (Rijndael
.Create ());
612 public void TripleDES_ANSIX923_Full ()
614 ANSIX923_Full (TripleDES
.Create ());
618 public void TripleDES_ANSIX923_Partial ()
620 ANSIX923_Partial (TripleDES
.Create ());
626 public void DES_ISO10126_Full ()
628 ISO10126_Full (DES
.Create ());
632 public void DES_ISO10126_Partial ()
634 ISO10126_Partial (DES
.Create ());
638 public void RC2_ISO10126_Full ()
640 ISO10126_Full (RC2
.Create ());
644 public void RC2_ISO10126_Partial ()
646 ISO10126_Partial (RC2
.Create ());
650 public void Rijndael_ISO10126_Full ()
652 ISO10126_Full (Rijndael
.Create ());
656 public void Rijndael_ISO10126_Partial ()
658 ISO10126_Partial (Rijndael
.Create ());
662 public void TripleDES_ISO10126_Full ()
664 ISO10126_Full (TripleDES
.Create ());
668 public void TripleDES_ISO10126_Partial ()
670 ISO10126_Partial (TripleDES
.Create ());
676 public void DES_PKCS7_Full ()
678 PKCS7_Full (DES
.Create ());
682 public void DES_PKCS7_Partial ()
684 PKCS7_Partial (DES
.Create ());
688 public void RC2_PKCS7_Full ()
690 PKCS7_Full (RC2
.Create ());
694 public void RC2_PKCS7_Partial ()
696 PKCS7_Partial (RC2
.Create ());
700 public void Rijndael_PKCS7_Full ()
702 PKCS7_Full (Rijndael
.Create ());
706 public void Rijndael_PKCS7_Partial ()
708 PKCS7_Partial (Rijndael
.Create ());
712 public void TripleDES_PKCS7_Full ()
714 PKCS7_Full (TripleDES
.Create ());
718 public void TripleDES_PKCS7_Partial ()
720 PKCS7_Partial (TripleDES
.Create ());
726 public void DES_Zeros_Full ()
728 Zeros_Full (DES
.Create ());
732 public void DES_Zeros_Partial ()
734 Zeros_Partial (DES
.Create ());
738 public void RC2_Zeros_Full ()
740 Zeros_Full (RC2
.Create ());
744 public void RC2_Zeros_Partial ()
746 Zeros_Partial (RC2
.Create ());
750 public void Rijndael_Zeros_Full ()
752 Zeros_Full (Rijndael
.Create ());
756 public void Rijndael_Zeros_Partial ()
758 Zeros_Partial (Rijndael
.Create ());
762 public void TripleDES_Zeros_Full ()
764 Zeros_Full (TripleDES
.Create ());
768 public void TripleDES_Zeros_Partial ()
770 Zeros_Partial (TripleDES
.Create ());
773 // Padding mismatches
775 // the best way to test bad padding is to:
776 // a. encrypt data larger than one block with a padding mode "X"
777 // b. decrypt the data with padding mode "Y" (different with Y)
778 // c. check if the "bad" padding was removed correctly
781 // 1 - length difference
782 // 2 - original data lost
783 // 4 - CryptographicException thrown while decryption
784 private int Mismatch (PaddingMode encrypt
, PaddingMode decrypt
)
786 SymmetricAlgorithm sa
= SymmetricAlgorithm
.Create ();
787 int bs
= (sa
.BlockSize
>> 3);
789 byte [] data
= new byte [bs
]; // in bytes
790 ICryptoTransform enc
= GetEncryptor (sa
, encrypt
);
791 byte [] encdata
= enc
.TransformFinalBlock (data
, 0, data
.Length
);
795 ICryptoTransform dec
= GetDecryptor (sa
, decrypt
);
796 byte [] decdata
= dec
.TransformFinalBlock (encdata
, 0, encdata
.Length
);
798 if (data
.Length
!= decdata
.Length
)
801 for (int i
=0; i
< data
.Length
; i
++) {
802 if (data
[i
] != decdata
[i
]) {
808 catch (CryptographicException
) {
815 public void ANSIX923_ISO10126 ()
817 Assert
.AreEqual (0, Mismatch (PaddingMode
.ANSIX923
, PaddingMode
.ISO10126
));
821 public void ANSIX923_None ()
823 Assert
.AreEqual (1, Mismatch (PaddingMode
.ANSIX923
, PaddingMode
.None
));
827 public void ANSIX923_PKCS7 ()
829 Assert
.AreEqual (0, Mismatch (PaddingMode
.ANSIX923
, PaddingMode
.PKCS7
));
833 public void ANSIX923_Zeros ()
835 Assert
.AreEqual (1, Mismatch (PaddingMode
.ANSIX923
, PaddingMode
.Zeros
));
839 public void ISO10126_ANSIX923 ()
841 Assert
.AreEqual (4, Mismatch (PaddingMode
.ISO10126
, PaddingMode
.ANSIX923
));
845 public void ISO10126_None ()
847 Assert
.AreEqual (1, Mismatch (PaddingMode
.ISO10126
, PaddingMode
.None
));
851 public void ISO10126_PKCS7 ()
853 Assert
.AreEqual (4, Mismatch (PaddingMode
.ISO10126
, PaddingMode
.PKCS7
));
857 public void ISO10126_Zeros ()
859 Assert
.AreEqual (1, Mismatch (PaddingMode
.ISO10126
, PaddingMode
.Zeros
));
863 public void None_ANSIX923 ()
865 Assert
.AreEqual (4, Mismatch (PaddingMode
.None
, PaddingMode
.ANSIX923
));
869 public void None_ISO10126 ()
871 Assert
.AreEqual (4, Mismatch (PaddingMode
.None
, PaddingMode
.ISO10126
));
875 public void None_PKCS7 ()
878 Assert
.AreEqual (4, Mismatch (PaddingMode
.None
, PaddingMode
.PKCS7
));
880 Assert
.AreEqual (0, Mismatch (PaddingMode
.None
, PaddingMode
.PKCS7
));
885 public void None_Zeros ()
887 Assert
.AreEqual (0, Mismatch (PaddingMode
.None
, PaddingMode
.Zeros
));
891 public void PKCS7_ANSIX923 ()
893 Assert
.AreEqual (4, Mismatch (PaddingMode
.PKCS7
, PaddingMode
.ANSIX923
));
897 public void PKCS7_ISO10126 ()
899 Assert
.AreEqual (0, Mismatch (PaddingMode
.PKCS7
, PaddingMode
.ISO10126
));
903 public void PKCS7_None ()
905 Assert
.AreEqual (1, Mismatch (PaddingMode
.PKCS7
, PaddingMode
.None
));
909 public void PKCS7_Zeros ()
911 Assert
.AreEqual (1, Mismatch (PaddingMode
.PKCS7
, PaddingMode
.Zeros
));
915 public void Zeros_ANSIX923 ()
917 Assert
.AreEqual (4, Mismatch (PaddingMode
.Zeros
, PaddingMode
.ANSIX923
));
921 public void Zeros_ISO10126 ()
923 Assert
.AreEqual (4, Mismatch (PaddingMode
.Zeros
, PaddingMode
.ISO10126
));
927 public void Zeros_None ()
929 Assert
.AreEqual (0, Mismatch (PaddingMode
.Zeros
, PaddingMode
.None
));
933 public void Zeros_PKCS7 ()
936 Assert
.AreEqual (4, Mismatch (PaddingMode
.Zeros
, PaddingMode
.PKCS7
));
938 Assert
.AreEqual (0, Mismatch (PaddingMode
.Zeros
, PaddingMode
.PKCS7
));
942 // MACTripleDES tests
944 private string MAC (PaddingMode padding
, int length
)
946 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 }
;
947 MACTripleDES mac
= new MACTripleDES (key
);
948 mac
.Padding
= padding
;
949 byte[] data
= new byte [length
];
950 byte[] hash
= mac
.TransformFinalBlock (data
, 0, data
.Length
);
951 string result
= BitConverter
.ToString (mac
.Hash
);
955 // Note: TripleDES block size is 8 bytes
958 public void MACTripleDES_ANSIX923 ()
960 Assert
.AreEqual ("F6-61-3E-C8-E4-A4-D1-A8", MAC (PaddingMode
.ANSIX923
, 8), "Full");
961 Assert
.AreEqual ("62-C3-78-B0-27-FC-EB-E0", MAC (PaddingMode
.ANSIX923
, 4), "Partial");
965 public void MACTripleDES_ISO10126 ()
967 // ISO 10126 use random in it's padding so we can't use it to get "repeatable" results
968 // (i.e. each call will get different result). This isn't a padding to use for MACing!!!
969 Assert
.AreEqual (23, MAC (PaddingMode
.ISO10126
, 8).Length
, "Full");
970 Assert
.AreEqual (23, MAC (PaddingMode
.ISO10126
, 4).Length
, "Partial");
974 public void MACTripleDES_None ()
976 Assert
.AreEqual ("46-34-5C-8E-EB-DC-74-5C", MAC (PaddingMode
.None
, 8), "Full");
980 [ExpectedException (typeof (CryptographicException
))]
981 public void MACTripleDES_None_Partial ()
983 // Illegal - must be a multiple of block size
984 MAC (PaddingMode
.None
, 4);
988 public void MACTripleDES_PKCS7 ()
990 Assert
.AreEqual ("17-71-9F-D5-0B-EF-1D-07", MAC (PaddingMode
.PKCS7
, 8), "Full");
991 Assert
.AreEqual ("5B-3A-13-6F-3F-6F-13-22", MAC (PaddingMode
.PKCS7
, 4), "Partial");
995 public void MACTripleDES_Zeros ()
997 Assert
.AreEqual ("46-34-5C-8E-EB-DC-74-5C", MAC (PaddingMode
.Zeros
, 8));
998 Assert
.AreEqual ("46-34-5C-8E-EB-DC-74-5C", MAC (PaddingMode
.Zeros
, 4));