1 // 2 // SHA256TestBase.cs - NUnit Test Cases for SHA256 3 // 4 // Author: 5 // Sebastien Pouliot <sebastien@ximian.com> 6 // 7 // (C) 2002 Motus Technologies Inc. (http://www.motus.com) 8 // Copyright (C) 2004, 2007-2008 Novell, Inc (http://www.novell.com) 9 // 10 11 using NUnit.Framework; 12 using System; 13 using System.IO; 14 using System.Security.Cryptography; 15 using System.Text; 16 17 namespace MonoTests.System.Security.Cryptography { 18 19 // References: 20 // a. FIPS PUB 180-2: Secure Hash Standard 21 // http://csrc.nist.gov/publications/fips/fips180-2/fip180-2.txt 22 23 // SHA256 is a abstract class - so most of the test included here wont be tested 24 // on the abstract class but should be tested in ALL its descendants. 25 26 // we can't make this a [TestFixture] since the class is shared with System.Core 27 // and causes issues in XA where these are in the same process. 28 public abstract class SHA256TestBase : HashAlgorithmTestBase { 29 30 [SetUp] SetUp()31 public override void SetUp () 32 { 33 hash = SHA256.Create (); 34 } 35 36 // the hash algorithm only exists as a managed implementation 37 public override bool ManagedHashImplementation { 38 get { return true; } 39 } 40 41 // test vectors from NIST FIPS 186-2 42 43 private string input1 = "abc"; 44 private string input2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 45 FIPS186_Test1(SHA256 hash)46 public void FIPS186_Test1 (SHA256 hash) 47 { 48 string className = hash.ToString (); 49 byte[] result = { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 50 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 51 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 52 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }; 53 byte[] input = Encoding.Default.GetBytes (input1); 54 55 string testName = className + " 1"; 56 FIPS186_a (testName, hash, input, result); 57 FIPS186_b (testName, hash, input, result); 58 FIPS186_c (testName, hash, input, result); 59 FIPS186_d (testName, hash, input, result); 60 FIPS186_e (testName, hash, input, result); 61 } 62 FIPS186_Test2(SHA256 hash)63 public void FIPS186_Test2 (SHA256 hash) 64 { 65 string className = hash.ToString (); 66 byte[] result = { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 67 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 68 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 69 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }; 70 byte[] input = Encoding.Default.GetBytes (input2); 71 72 string testName = className + " 2"; 73 FIPS186_a (testName, hash, input, result); 74 FIPS186_b (testName, hash, input, result); 75 FIPS186_c (testName, hash, input, result); 76 FIPS186_d (testName, hash, input, result); 77 FIPS186_e (testName, hash, input, result); 78 } 79 FIPS186_Test3(SHA256 hash)80 public void FIPS186_Test3 (SHA256 hash) 81 { 82 string className = hash.ToString (); 83 byte[] result = { 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 84 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67, 85 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 86 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 }; 87 byte[] input = new byte [1000000]; 88 for (int i = 0; i < 1000000; i++) 89 input[i] = 0x61; // a 90 91 string testName = className + " 3"; 92 FIPS186_a (testName, hash, input, result); 93 FIPS186_b (testName, hash, input, result); 94 FIPS186_c (testName, hash, input, result); 95 FIPS186_d (testName, hash, input, result); 96 FIPS186_e (testName, hash, input, result); 97 } 98 FIPS186_a(string testName, SHA256 hash, byte[] input, byte[] result)99 public void FIPS186_a (string testName, SHA256 hash, byte[] input, byte[] result) 100 { 101 byte[] output = hash.ComputeHash (input); 102 Assert.AreEqual (result, output, testName + ".a.1"); 103 Assert.AreEqual (result, hash.Hash, testName + ".a.2"); 104 // required or next operation will still return old hash 105 hash.Initialize (); 106 } 107 FIPS186_b(string testName, SHA256 hash, byte[] input, byte[] result)108 public void FIPS186_b (string testName, SHA256 hash, byte[] input, byte[] result) 109 { 110 byte[] output = hash.ComputeHash (input, 0, input.Length); 111 Assert.AreEqual (result, output, testName + ".b.1"); 112 Assert.AreEqual (result, hash.Hash, testName + ".b.2"); 113 // required or next operation will still return old hash 114 hash.Initialize (); 115 } 116 FIPS186_c(string testName, SHA256 hash, byte[] input, byte[] result)117 public void FIPS186_c (string testName, SHA256 hash, byte[] input, byte[] result) 118 { 119 MemoryStream ms = new MemoryStream (input); 120 byte[] output = hash.ComputeHash (ms); 121 Assert.AreEqual (result, output, testName + ".c.1"); 122 Assert.AreEqual (result, hash.Hash, testName + ".c.2"); 123 // required or next operation will still return old hash 124 hash.Initialize (); 125 } 126 FIPS186_d(string testName, SHA256 hash, byte[] input, byte[] result)127 public void FIPS186_d (string testName, SHA256 hash, byte[] input, byte[] result) 128 { 129 byte[] output = hash.TransformFinalBlock (input, 0, input.Length); 130 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue ! 131 // AssertEquals( testName + ".d.1", result, output ); 132 Assert.IsNotNull (output, testName + ".d.1"); 133 Assert.AreEqual (result, hash.Hash, testName + ".d.2"); 134 // required or next operation will still return old hash 135 hash.Initialize (); 136 } 137 FIPS186_e(string testName, SHA256 hash, byte[] input, byte[] result)138 public void FIPS186_e (string testName, SHA256 hash, byte[] input, byte[] result) 139 { 140 byte[] copy = new byte [input.Length]; 141 for (int i=0; i < input.Length - 1; i++) 142 hash.TransformBlock (input, i, 1, copy, i); 143 byte[] output = hash.TransformFinalBlock (input, input.Length - 1, 1); 144 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue ! 145 // AssertEquals (testName + ".e.1", result, output); 146 Assert.IsNotNull (output, testName + ".e.1"); 147 Assert.AreEqual (result, hash.Hash, testName + ".e.2"); 148 // required or next operation will still return old hash 149 hash.Initialize (); 150 } 151 152 [Test] Create()153 public override void Create () 154 { 155 // Note: These tests will only be valid without a "machine.config" file 156 // or a "machine.config" file that do not modify the default algorithm 157 // configuration. 158 const string defaultSHA256 = "System.Security.Cryptography.SHA256Managed"; 159 160 // try to build the default implementation 161 SHA256 hash = SHA256.Create (); 162 Assert.AreEqual (hash.ToString (), defaultSHA256, "SHA256.Create()"); 163 164 // try to build, in every way, a SHA256 implementation 165 hash = SHA256.Create ("SHA256"); 166 Assert.AreEqual (hash.ToString (), defaultSHA256, "SHA256.Create('SHA256')"); 167 hash = SHA256.Create ("SHA-256"); 168 Assert.AreEqual (hash.ToString (), defaultSHA256, "SHA256.Create('SHA-256')"); 169 } 170 171 [Test] 172 [ExpectedException (typeof (InvalidCastException))] CreateIncorrect()173 public void CreateIncorrect () 174 { 175 // try to build an incorrect hash algorithms 176 hash = SHA256.Create ("MD5"); 177 } 178 179 [Test] CreateInvalid()180 public void CreateInvalid () 181 { 182 // try to build invalid implementation 183 hash = SHA256.Create ("InvalidHash"); 184 Assert.IsNull (hash, "SHA256.Create('InvalidHash')"); 185 } 186 187 [Test] 188 [ExpectedException (typeof (ArgumentNullException))] CreateNull()189 public override void CreateNull () 190 { 191 // try to build null implementation 192 hash = SHA256.Create (null); 193 } 194 195 // none of those values changes for any implementation of defaultSHA256 196 [Test] StaticInfo()197 public virtual void StaticInfo () 198 { 199 string className = hash.ToString (); 200 Assert.AreEqual (256, hash.HashSize, className + ".HashSize"); 201 Assert.AreEqual (1, hash.InputBlockSize, className + ".InputBlockSize"); 202 Assert.AreEqual (1, hash.OutputBlockSize, className + ".OutputBlockSize"); 203 } 204 } 205 206 } 207