1 // 2 // MACTripleDESTest.cs - NUnit Test Cases for MACTripleDES 3 // 4 // Author: 5 // Sebastien Pouliot (sebastien@ximian.com) 6 // 7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) 8 // Copyright (C) 2004 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. 28 // 29 30 using NUnit.Framework; 31 using System; 32 using System.IO; 33 using System.Security.Cryptography; 34 35 namespace MonoTests.System.Security.Cryptography { 36 37 [TestFixture] 38 public class MACTripleDESTest { 39 40 protected MACTripleDES algo; 41 42 private static byte[] key1 = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; 43 private static byte[] key2 = { 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01 }; 44 private static byte[] key3 = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; 45 AssertEquals(string msg, byte[] array1, byte[] array2)46 public void AssertEquals (string msg, byte[] array1, byte[] array2) 47 { 48 AllTests.AssertEquals (msg, array1, array2); 49 } 50 CombineKeys(byte[] key1, byte[] key2, byte[] key3)51 protected byte[] CombineKeys (byte[] key1, byte[] key2, byte[] key3) 52 { 53 int k1l = key1.Length; 54 int k2l = key2.Length; 55 int k3l = key3.Length; 56 byte[] key = new byte [k1l + k2l + k3l]; 57 Array.Copy (key1, 0, key, 0, k1l); 58 Array.Copy (key2, 0, key, k1l, k2l); 59 Array.Copy (key3, 0, key, k1l + k2l, k3l); 60 return key; 61 } 62 63 [Test] ConstructorEmpty()64 public void ConstructorEmpty () 65 { 66 algo = new MACTripleDES (); 67 } 68 69 [Test] ConstructorKey()70 public void ConstructorKey () 71 { 72 byte[] key = CombineKeys (key1, key2, key3); 73 algo = new MACTripleDES (key); 74 } 75 76 [Test] 77 [ExpectedException (typeof (ArgumentNullException))] ConstructorKeyNull()78 public void ConstructorKeyNull () 79 { 80 algo = new MACTripleDES (null); 81 } 82 83 [Test] ConstructorNameKey()84 public void ConstructorNameKey () 85 { 86 byte[] key = CombineKeys (key1, key2, key3); 87 algo = new MACTripleDES ("TripleDES", key); 88 } 89 90 [Test] 91 // LAMESPEC: [ExpectedException (typeof (ArgumentNullException))] ConstructorNameNullKey()92 public void ConstructorNameNullKey () 93 { 94 byte[] key = CombineKeys (key1, key2, key3); 95 // funny null is a valid name! 96 algo = new MACTripleDES (null, key); 97 } 98 99 [Test] 100 [ExpectedException (typeof (ArgumentNullException))] ConstructorNameNullKeyNull()101 public void ConstructorNameNullKeyNull () 102 { 103 algo = new MACTripleDES (null, null); 104 } 105 106 [Test] Invariants()107 public void Invariants () 108 { 109 algo = new MACTripleDES (); 110 Assert.IsTrue (algo.CanReuseTransform, "MACTripleDES.CanReuseTransform"); 111 Assert.IsTrue (algo.CanTransformMultipleBlocks, "MACTripleDES.CanTransformMultipleBlocks"); 112 Assert.AreEqual (64, algo.HashSize, "MACTripleDES.HashSize"); 113 Assert.AreEqual (1, algo.InputBlockSize, "MACTripleDES.InputBlockSize"); 114 Assert.AreEqual (1, algo.OutputBlockSize, "MACTripleDES.OutputBlockSize"); 115 Assert.AreEqual ("System.Security.Cryptography.MACTripleDES", algo.ToString (), "MACTripleDES.ToString()"); 116 Assert.IsNotNull (algo.Key, "MACTripleDES.Key"); 117 } 118 119 [Test] 120 [ExpectedException (typeof (InvalidCastException))] InvalidAlgorithmName()121 public void InvalidAlgorithmName () 122 { 123 byte[] key = CombineKeys (key1, key2, key3); 124 algo = new MACTripleDES ("DES", key); 125 } 126 127 [Test] 128 [ExpectedException (typeof (ObjectDisposedException))] ObjectDisposed()129 public void ObjectDisposed () 130 { 131 byte[] key = CombineKeys (key1, key2, key3); 132 algo = new MACTripleDES (key); 133 algo.Clear (); 134 algo.ComputeHash (new byte[1]); 135 } 136 Check(string testName, byte[] key, byte[] data, byte[] result)137 public void Check (string testName, byte[] key, byte[] data, byte[] result) 138 { 139 string classTestName = "MACTripleDES-" + testName; 140 CheckA (testName, key, data, result); 141 CheckB (testName, key, data, result); 142 CheckC (testName, key, data, result); 143 CheckD (testName, key, data, result); 144 CheckE (testName, key, data, result); 145 } 146 147 // - Test constructor #1 () 148 // - Test ComputeHash (byte[]); CheckA(string testName, byte[] key, byte[] data, byte[] result)149 public void CheckA (string testName, byte[] key, byte[] data, byte[] result) 150 { 151 algo = new MACTripleDES (); 152 algo.Key = key; 153 byte[] hmac = algo.ComputeHash (data); 154 AssertEquals (testName + "a1", result, hmac); 155 AssertEquals (testName + "a2", result, algo.Hash); 156 } 157 158 // - Test constructor #2 (byte[]) 159 // - Test ComputeHash (byte[], int, int); CheckB(string testName, byte[] key, byte[] data, byte[] result)160 public void CheckB (string testName, byte[] key, byte[] data, byte[] result) 161 { 162 algo = new MACTripleDES (key); 163 byte[] hmac = algo.ComputeHash (data, 0, data.Length); 164 AssertEquals (testName + "b1", result, hmac); 165 AssertEquals (testName + "b2", result, algo.Hash); 166 } 167 168 // - Test constructor #3 (string, byte[]) 169 // - Test ComputeHash (stream); CheckC(string testName, byte[] key, byte[] data, byte[] result)170 public void CheckC (string testName, byte[] key, byte[] data, byte[] result) 171 { 172 algo = new MACTripleDES ("TripleDES", key); 173 algo.Key = key; 174 MemoryStream ms = new MemoryStream (data); 175 byte[] hmac = algo.ComputeHash (ms); 176 AssertEquals (testName + "c1", result, hmac); 177 AssertEquals (testName + "c2", result, algo.Hash); 178 } 179 180 // - Test TransformFinalBlock - alone; CheckD(string testName, byte[] key, byte[] data, byte[] result)181 public void CheckD (string testName, byte[] key, byte[] data, byte[] result) 182 { 183 algo = new MACTripleDES (); 184 algo.Key = key; 185 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue ! 186 algo.TransformFinalBlock (data, 0, data.Length); 187 AssertEquals (testName + "d", result, algo.Hash); 188 } 189 190 // - Test TransformBlock/TransformFinalBlock CheckE(string testName, byte[] key, byte[] data, byte[] result)191 public void CheckE (string testName, byte[] key, byte[] data, byte[] result) 192 { 193 algo = new MACTripleDES (); 194 algo.Key = key; 195 byte[] copy = new byte [data.Length]; 196 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue ! 197 for (int i=0; i < data.Length - 1; i++) 198 algo.TransformBlock (data, i, 1, copy, i); 199 algo.TransformFinalBlock (data, data.Length - 1, 1); 200 AssertEquals (testName + "e", result, algo.Hash); 201 } 202 203 // Here data is smaller than the 3DES block size (8 bytes) 204 [Test] SmallerThanOneBlockSize()205 public void SmallerThanOneBlockSize () 206 { 207 byte[] key = CombineKeys (key1, key2, key3); 208 byte[] expected = { 0x86, 0xE9, 0x65, 0xBD, 0x1E, 0xC4, 0x44, 0x61 }; 209 byte[] data = new byte [7]; 210 Check ("3DESMAC-A1", key, data, expected); 211 } 212 213 // Here data is exactly one 3DES block size (8 bytes) 214 [Test] ExactlyOneBlockSize()215 public void ExactlyOneBlockSize () 216 { 217 byte[] key = CombineKeys (key1, key2, key3); 218 byte [] expected = { 0x86, 0xE9, 0x65, 0xBD, 0x1E, 0xC4, 0x44, 0x61 }; 219 byte[] data = new byte [8]; 220 Check ("3DESMAC-A2", key, data, expected); 221 } 222 223 // Here data is more then one 3DES block size (8 bytes) 224 [Test] MoreThanOneBlockSize()225 public void MoreThanOneBlockSize () 226 { 227 byte[] key = CombineKeys (key1, key2, key3); 228 // note: same result as A2 because of the Zero padding (and that 229 // we use zeros as data 230 byte[] expected = { 0x23, 0xD6, 0x92, 0xA0, 0x80, 0x6E, 0xC9, 0x30 }; 231 byte[] data = new byte [14]; 232 Check ("3DESMAC-A3", key, data, expected); 233 } 234 235 // Here data is a multiple of 3DES block size (8 bytes) 236 [Test] ExactMultipleBlockSize()237 public void ExactMultipleBlockSize () 238 { 239 byte[] key = CombineKeys (key1, key2, key3); 240 byte [] expected = { 0xA3, 0x0E, 0x34, 0x26, 0x8B, 0x49, 0xEF, 0x49 }; 241 byte[] data = new byte [48]; 242 Check ("3DESMAC-A4", key, data, expected); 243 } 244 } 245 246 }