2 // TestSuite.System.Security.Cryptography.DESTest.cs
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2004 Novell (http://www.novell.com)
11 using System.Security.Cryptography;
14 using NUnit.Framework;
16 namespace MonoTests.System.Security.Cryptography {
19 public class DESTest : Assertion {
21 static byte[] wk1 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
22 static byte[] wk2 = { 0x1E, 0x1E, 0x1E, 0x1E, 0x0F, 0x0F, 0x0F, 0x0F };
23 static byte[] wk3 = { 0xE1, 0xE1, 0xE1, 0xE1, 0xF0, 0xF0, 0xF0, 0xF0 };
24 static byte[] wk4 = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
27 static byte[] wk1p = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
28 static byte[] wk2p = { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E };
29 static byte[] wk3p = { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 };
30 static byte[] wk4p = { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE };
33 public void WeakKeys_WithoutParity ()
35 Assert ("WK-1", DES.IsWeakKey (wk1));
36 Assert ("WK-2", DES.IsWeakKey (wk2));
37 Assert ("WK-3", DES.IsWeakKey (wk3));
38 Assert ("WK-4", DES.IsWeakKey (wk4));
42 public void WeakKeys_WithParity ()
44 Assert ("WK-1P", DES.IsWeakKey (wk1p));
45 Assert ("WK-2P", DES.IsWeakKey (wk2p));
46 Assert ("WK-3P", DES.IsWeakKey (wk3p));
47 Assert ("WK-4P", DES.IsWeakKey (wk4p));
51 [ExpectedException (typeof (CryptographicException))]
52 public void IsWeakKey_WrongKeyLength ()
54 byte[] key = new byte [16]; // 128 bits
59 [ExpectedException (typeof (NullReferenceException))]
60 public void IsWeakKey_Null ()
65 static byte[] swk1 = { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF };
66 static byte[] swk2 = { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 };
67 static byte[] swk3 = { 0x1E, 0xE1, 0x1E, 0xE1, 0x0F, 0xF0, 0x0F, 0xF0 };
68 static byte[] swk4 = { 0xE1, 0x1E, 0xE1, 0x1E, 0xF0, 0x0F, 0xF0, 0x0F };
69 static byte[] swk5 = { 0x00, 0xE1, 0x00, 0xE1, 0x00, 0xF0, 0x00, 0xF0 };
70 static byte[] swk6 = { 0xE1, 0x00, 0xE1, 0x00, 0xF0, 0x00, 0xF0, 0x00 };
71 static byte[] swk7 = { 0x1E, 0xFF, 0x1E, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF };
72 static byte[] swk8 = { 0xFF, 0x1E, 0xFF, 0x1E, 0xFF, 0x0F, 0xFF, 0x0F };
73 static byte[] swk9 = { 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x0F };
74 static byte[] swk10 = { 0x1E, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x0F, 0x00 };
75 static byte[] swk11 = { 0xE1, 0xFF, 0xE1, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF };
76 static byte[] swk12 = { 0xFF, 0xE1, 0xFF, 0xE1, 0xFF, 0xF0, 0xFF, 0xF0 };
78 static byte[] swk1p = { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE };
79 static byte[] swk2p = { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 };
80 static byte[] swk3p = { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 };
81 static byte[] swk4p = { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E };
82 static byte[] swk5p = { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 };
83 static byte[] swk6p = { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 };
84 static byte[] swk7p = { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE };
85 static byte[] swk8p = { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E };
86 static byte[] swk9p = { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E };
87 static byte[] swk10p = { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 };
88 static byte[] swk11p = { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE };
89 static byte[] swk12p = { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 };
92 public void SemiWeakKeys_WithoutParity ()
94 Assert ("SWK-01", DES.IsSemiWeakKey (swk1));
95 Assert ("SWK-02", DES.IsSemiWeakKey (swk2));
96 Assert ("SWK-03", DES.IsSemiWeakKey (swk3));
97 Assert ("SWK-04", DES.IsSemiWeakKey (swk4));
98 Assert ("SWK-05", DES.IsSemiWeakKey (swk5));
99 Assert ("SWK-06", DES.IsSemiWeakKey (swk6));
100 Assert ("SWK-07", DES.IsSemiWeakKey (swk7));
101 Assert ("SWK-08", DES.IsSemiWeakKey (swk8));
102 Assert ("SWK-09", DES.IsSemiWeakKey (swk9));
103 Assert ("SWK-10", DES.IsSemiWeakKey (swk10));
104 Assert ("SWK-11", DES.IsSemiWeakKey (swk11));
105 Assert ("SWK-12", DES.IsSemiWeakKey (swk12));
109 public void SemiWeakKeys_WithParity ()
111 Assert ("SWK-01P", DES.IsSemiWeakKey (swk1p));
112 Assert ("SWK-02P", DES.IsSemiWeakKey (swk2p));
113 Assert ("SWK-03P", DES.IsSemiWeakKey (swk3p));
114 Assert ("SWK-04P", DES.IsSemiWeakKey (swk4p));
115 Assert ("SWK-05P", DES.IsSemiWeakKey (swk5p));
116 Assert ("SWK-06P", DES.IsSemiWeakKey (swk6p));
117 Assert ("SWK-07P", DES.IsSemiWeakKey (swk7p));
118 Assert ("SWK-08P", DES.IsSemiWeakKey (swk8p));
119 Assert ("SWK-09P", DES.IsSemiWeakKey (swk9p));
120 Assert ("SWK-10P", DES.IsSemiWeakKey (swk10p));
121 Assert ("SWK-11P", DES.IsSemiWeakKey (swk11p));
122 Assert ("SWK-12P", DES.IsSemiWeakKey (swk12p));
126 [ExpectedException (typeof (CryptographicException))]
127 public void IsSemiWeakKey_WrongKeyLength ()
129 byte[] key = new byte [16]; // 128 bits
130 DES.IsSemiWeakKey (key);
134 [ExpectedException (typeof (NullReferenceException))]
135 public void IsSemiWeakKey_Null ()
137 DES.IsSemiWeakKey (null);
141 public void GetKey ()
143 DES des = DES.Create ();
144 byte[] key = des.Key;
145 AssertEquals ("64 bits", 8, key.Length);
147 // we get a copy of the key (not the original)
148 string s = BitConverter.ToString (key);
150 AssertEquals ("Copy", s, BitConverter.ToString (key));
154 [ExpectedException (typeof (ArgumentNullException))]
155 public void SetKey_Null ()
157 DES des = DES.Create ();
162 [ExpectedException (typeof (ArgumentException))]
163 public void SetKey_WrongLength ()
165 DES des = DES.Create ();
166 des.Key = new byte [16]; // 128 bits
170 [ExpectedException (typeof (CryptographicException))]
171 public void SetKey_Weak ()
173 DES des = DES.Create ();
178 [ExpectedException (typeof (CryptographicException))]
179 public void SetKey_SemiWeak ()
181 DES des = DES.Create ();
186 // Test vectors from FIPS 81 - DES Modes of Operations
187 // http://csrc.nist.gov/publications/fips/fips81/fips81.htm
189 // Note: they are to be called from specifics implementations -
190 // not for the abstract DES. Thats why they are in a separate class
191 // which doesn't have a [TestFixture] attribute
192 public class DESFIPS81Test : Assertion {
195 // Table B1 - ECB Mode
197 public void FIPS81_ECBMode ()
199 byte[] plaintext = Encoding.ASCII.GetBytes ("Now is the time for all ");
200 byte[] result = new byte [24];
202 des.Key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
203 des.Mode = CipherMode.ECB;
204 des.Padding = PaddingMode.None;
205 ICryptoTransform encrypt = des.CreateEncryptor ();
207 encrypt.TransformBlock (plaintext, 0, 8, result, 0);
208 AssertEquals ("Encrypt Block 1", "3F-A4-0E-8A-98-4D-48-15", BitConverter.ToString (result, 0, 8));
210 encrypt.TransformBlock (plaintext, 8, 8, result, 8);
211 AssertEquals ("Encrypt Block 2", "6A-27-17-87-AB-88-83-F9", BitConverter.ToString (result, 8, 8));
213 encrypt.TransformBlock (plaintext, 16, 8, result, 16);
214 AssertEquals ("Encrypt Block 3", "89-3D-51-EC-4B-56-3B-53", BitConverter.ToString (result, 16, 8));
216 ICryptoTransform decrypt = des.CreateDecryptor ();
218 byte[] decrypted = new byte [24]; // MS cannot *always* reuse buffers
219 decrypt.TransformBlock (result, 0, 8, decrypted, 0);
220 AssertEquals ("Decrypt Block 1", "Now is t", Encoding.ASCII.GetString (decrypted, 0, 8));
222 decrypt.TransformBlock (result, 8, 8, decrypted, 8);
223 AssertEquals ("Decrypt Block 2", "he time ", Encoding.ASCII.GetString (decrypted, 8, 8));
225 decrypt.TransformBlock (result, 16, 8, decrypted, 16);
226 AssertEquals ("Decrypt Block 3", "for all ", Encoding.ASCII.GetString (decrypted, 16, 8));
229 // Table C1 - CBC Mode
231 public void FIPS81_CBCMode ()
233 byte[] plaintext = Encoding.ASCII.GetBytes ("Now is the time for all ");
234 byte[] result = new byte [24];
236 des.Key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
237 des.IV = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
238 des.Mode = CipherMode.CBC;
239 des.Padding = PaddingMode.None;
240 ICryptoTransform encrypt = des.CreateEncryptor ();
242 encrypt.TransformBlock (plaintext, 0, 8, result, 0);
243 AssertEquals ("Encrypt Block 1", "E5-C7-CD-DE-87-2B-F2-7C", BitConverter.ToString (result, 0, 8));
245 encrypt.TransformBlock (plaintext, 8, 8, result, 8);
246 AssertEquals ("Encrypt Block 2", "43-E9-34-00-8C-38-9C-0F", BitConverter.ToString (result, 8, 8));
248 byte[] final = encrypt.TransformFinalBlock (plaintext, 16, 8);
249 Buffer.BlockCopy (final, 0, result, 16, 8);
250 AssertEquals ("Encrypt Block 3", "68-37-88-49-9A-7C-05-F6", BitConverter.ToString (result, 16, 8));
252 ICryptoTransform decrypt = des.CreateDecryptor ();
254 decrypt.TransformBlock (result, 0, 8, result, 0);
255 AssertEquals ("Decrypt Block 1", "Now is t", Encoding.ASCII.GetString (result, 0, 8));
257 decrypt.TransformBlock (result, 8, 8, result, 8);
258 AssertEquals ("Decrypt Block 2", "he time ", Encoding.ASCII.GetString (result, 8, 8));
260 final = decrypt.TransformFinalBlock (result, 16, 8);
261 AssertEquals ("Decrypt Block 3", "for all ", Encoding.ASCII.GetString (final));
264 // Table D2 - CFB Mode 8 bits
266 public void FIPS81_CFB8Mode ()
268 byte[] plaintext = Encoding.ASCII.GetBytes ("Now is theXXXXXX"); // padding
269 byte[] result = new byte [16];
271 des.Key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
272 des.IV = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
273 des.Mode = CipherMode.CFB;
274 des.Padding = PaddingMode.None;
275 des.FeedbackSize = 8;
276 ICryptoTransform encrypt = des.CreateEncryptor ();
278 encrypt.TransformBlock (plaintext, 0, 8, result, 0);
279 AssertEquals ("Encrypt Block 1", "F3-1F-DA-07-01-14-62-EE", BitConverter.ToString (result, 0, 8));
281 byte[] final = encrypt.TransformFinalBlock (plaintext, 8, 8);
282 Buffer.BlockCopy (final, 0, result, 8, 8);
283 AssertEquals ("Encrypt Block 2", "18-7F", BitConverter.ToString (final).Substring (0, 5));
285 ICryptoTransform decrypt = des.CreateDecryptor ();
287 decrypt.TransformBlock (result, 0, 8, result, 0);
288 AssertEquals ("Decrypt Block 1", "Now is t", Encoding.ASCII.GetString (result, 0, 8));
290 final = decrypt.TransformFinalBlock (result, 8, 8);
291 AssertEquals ("Decrypt Block 2", "he", Encoding.ASCII.GetString (final, 0, 2));