1 //
2 // HMACSHA512Test.cs - NUnit Test Cases for HMACSHA512
3 //
4 // Author:
5 //	Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2006, 2007 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 	public class HS512 : HMACSHA512 {
20 
21 		public int BlockSize {
22 			get { return base.BlockSizeValue; }
23 			set { base.BlockSizeValue = value; }
24 		}
25 	}
26 
27 	public class SelectableHmacSha512: HMAC {
28 
29 		// Legacy parameter explanation:
30 		// http://blogs.msdn.com/shawnfa/archive/2007/01/31/please-do-not-use-the-net-2-0-hmacsha512-and-hmacsha384-classes.aspx
31 
SelectableHmacSha512(byte[] key, bool legacy)32 		public SelectableHmacSha512 (byte[] key, bool legacy)
33 		{
34 			HashName = "SHA512";
35 			HashSizeValue = 512;
36 			BlockSizeValue = legacy ? 64 : 128;
37 			Key = key;
38 		}
39 	}
40 
41 	// References:
42 	// a.	Identifiers and Test Vectors for HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512
43 	//	http://www.ietf.org/rfc/rfc4231.txt
44 
45 	[TestFixture]
46 	public class HMACSHA512Test : KeyedHashAlgorithmTest {
47 
48 		protected HMACSHA512 algo;
49 
50 		[SetUp]
SetUp()51 		public override void SetUp ()
52 		{
53 			algo = new HMACSHA512 ();
54 			algo.Key = new byte [8];
55 			hash = algo;
56 		}
57 
58 		// the hash algorithm only exists as a managed implementation
59 		public override bool ManagedHashImplementation {
60 			get { return true; }
61 		}
62 
63 		[Test]
Constructors()64 		public void Constructors ()
65 		{
66 			algo = new HMACSHA512 ();
67 			Assert.IsNotNull (algo, "HMACSHA512 ()");
68 
69 			byte[] key = new byte [8];
70 			algo = new HMACSHA512 (key);
71 			Assert.IsNotNull (algo, "HMACSHA512 (key)");
72 		}
73 
74 		[Test]
75 		[ExpectedException (typeof (NullReferenceException))]
Constructor_Null()76 		public void Constructor_Null ()
77 		{
78 			new HMACSHA512 (null);
79 		}
80 
81 		[Test]
Invariants()82 		public void Invariants ()
83 		{
84 			algo = new HMACSHA512 ();
85 			Assert.IsTrue (algo.CanReuseTransform, "HMACSHA512.CanReuseTransform");
86 			Assert.IsTrue (algo.CanTransformMultipleBlocks, "HMACSHA512.CanTransformMultipleBlocks");
87 			Assert.AreEqual ("SHA512", algo.HashName, "HMACSHA512.HashName");
88 			Assert.AreEqual (512, algo.HashSize, "HMACSHA512.HashSize");
89 			Assert.AreEqual (1, algo.InputBlockSize, "HMACSHA512.InputBlockSize");
90 			Assert.AreEqual (1, algo.OutputBlockSize, "HMACSHA512.OutputBlockSize");
91 			Assert.AreEqual (128, algo.Key.Length, "HMACSHA512.Key.Length");
92 			Assert.AreEqual ("System.Security.Cryptography.HMACSHA512", algo.ToString (), "HMACSHA512.ToString()");
93 		}
94 
95 		// some test case truncate the result
Compare(byte[] expected, byte[] actual, string msg)96 		private void Compare (byte[] expected, byte[] actual, string msg)
97 		{
98 			if (expected.Length == actual.Length) {
99 				Assert.AreEqual (expected, actual, msg);
100 			} else {
101 				byte[] data = new byte [expected.Length];
102 				Array.Copy (actual, data, data.Length);
103 				Assert.AreEqual (expected, data, msg);
104 			}
105 		}
106 
Check(string testName, HMAC algo, byte[] data, byte[] result)107 		public void Check (string testName, HMAC algo, byte[] data, byte[] result)
108 		{
109 			CheckA (testName, algo, data, result);
110 			CheckB (testName, algo, data, result);
111 			CheckC (testName, algo, data, result);
112 			CheckD (testName, algo, data, result);
113 			CheckE (testName, algo, data, result);
114 		}
115 
CheckA(string testName, HMAC algo, byte[] data, byte[] result)116 		public void CheckA (string testName, HMAC algo, byte[] data, byte[] result)
117 		{
118 			byte[] hmac = algo.ComputeHash (data);
119 			Compare (result, hmac, testName + "a1");
120 			Compare (result, algo.Hash, testName + "a2");
121 		}
122 
CheckB(string testName, HMAC algo, byte[] data, byte[] result)123 		public void CheckB (string testName, HMAC algo, byte[] data, byte[] result)
124 		{
125 			byte[] hmac = algo.ComputeHash (data, 0, data.Length);
126 			Compare (result, hmac, testName + "b1");
127 			Compare (result, algo.Hash, testName + "b2");
128 		}
129 
CheckC(string testName, HMAC algo, byte[] data, byte[] result)130 		public void CheckC (string testName, HMAC algo, byte[] data, byte[] result)
131 		{
132 			using (MemoryStream ms = new MemoryStream (data)) {
133 				byte[] hmac = algo.ComputeHash (ms);
134 				Compare (result, hmac, testName + "c1");
135 				Compare (result, algo.Hash, testName + "c2");
136 			}
137 		}
138 
CheckD(string testName, HMAC algo, byte[] data, byte[] result)139 		public void CheckD (string testName, HMAC algo, byte[] data, byte[] result)
140 		{
141 			algo.TransformFinalBlock (data, 0, data.Length);
142 			Compare (result, algo.Hash, testName + "d");
143 			algo.Initialize ();
144 		}
145 
CheckE(string testName, HMAC algo, byte[] data, byte[] result)146 		public void CheckE (string testName, HMAC algo, byte[] data, byte[] result)
147 		{
148 			byte[] copy = new byte[data.Length];
149 			for (int i = 0; i < data.Length - 1; i++)
150 				algo.TransformBlock (data, i, 1, copy, i);
151 			algo.TransformFinalBlock (data, data.Length - 1, 1);
152 			Compare (result, algo.Hash, testName + "e");
153 			algo.Initialize ();
154 		}
155 
156 		[Test]
RFC4231_TC1_Normal()157 		public void RFC4231_TC1_Normal ()
158 		{
159 			byte[] key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
160 			byte[] data = Encoding.Default.GetBytes ("Hi There");
161 			byte[] digest = { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
162 				0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78, 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
163 				0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02, 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
164 				0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 };
165 			HMAC hmac = new SelectableHmacSha512 (key, false);
166 			Check ("HMACSHA512-N-RFC4231-TC1", hmac, data, digest);
167 		}
168 
169 		[Test]
170 		// Test with a key shorter than the length of the HMAC output.
RFC4231_TC2_Normal()171 		public void RFC4231_TC2_Normal ()
172 		{
173 			byte[] key = Encoding.Default.GetBytes ("Jefe");
174 			byte[] data = Encoding.Default.GetBytes ("what do ya want for nothing?");
175 			byte[] digest = { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
176 				0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6, 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
177 				0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a, 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
178 				0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b, 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 };
179 			HMAC hmac = new SelectableHmacSha512 (key, false);
180 			Check ("HMACSHA512-N-RFC4231-TC2", hmac, data, digest);
181 		}
182 
183 		[Test]
184 		// Test with a combined length of key and data that is larger than 64 bytes (= block-size of SHA-224 and SHA-256).
RFC4231_TC3_Normal()185 		public void RFC4231_TC3_Normal ()
186 		{
187 			byte[] key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
188 			byte[] data = { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
189 				0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
190 				0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
191 				0xdd, 0xdd };
192 			byte[] digest = { 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
193 				0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36, 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
194 				0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8, 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
195 				0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26, 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb };
196 			HMAC hmac = new SelectableHmacSha512 (key, false);
197 			Check ("HMACSHA512-N-RFC4231-TC3", hmac, data, digest);
198 		}
199 
200 		[Test]
201 		// Test with a combined length of key and data that is larger than 64 bytes (= block-size of SHA-224 and SHA-256).
RFC4231_TC4_Normal()202 		public void RFC4231_TC4_Normal ()
203 		{
204 			byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
205 				0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 };
206 			byte[] data = { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
207 				0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
208 				0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
209 				0xcd, 0xcd };
210 			byte[] digest = { 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69, 0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
211 				0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d, 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
212 				0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4, 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
213 				0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d, 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd };
214 			HMAC hmac = new SelectableHmacSha512 (key, false);
215 			Check ("HMACSHA512-N-RFC4231-TC4", hmac, data, digest);
216 		}
217 
218 		[Test]
219 		// Test with a truncation of output to 128 bits.
RFC4231_TC5_Normal()220 		public void RFC4231_TC5_Normal ()
221 		{
222 			byte[] key = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
223 				0x0c, 0x0c, 0x0c, 0x0c };
224 			byte[] data = Encoding.Default.GetBytes ("Test With Truncation");
225 			byte[] digest = { 0x41, 0x5f, 0xad, 0x62, 0x71, 0x58, 0x0a, 0x53, 0x1d, 0x41, 0x79, 0xbc, 0x89, 0x1d, 0x87, 0xa6 };
226 			HMAC hmac = new SelectableHmacSha512 (key, false);
227 			Check ("HMACSHA512-N-RFC4231-TC5", hmac, data, digest);
228 		}
229 
230 		[Test]
231 		// Test with a key larger than 128 bytes (= block-size of SHA-384 and SHA-512).
RFC4231_TC6_Normal()232 		public void RFC4231_TC6_Normal ()
233 		{
234 			byte[] key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
235 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
236 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
237 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
238 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
239 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
240 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
241 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
242 				0xaa, 0xaa, 0xaa };
243 			byte[] data = Encoding.Default.GetBytes ("Test Using Larger Than Block-Size Key - Hash Key First");
244 			byte[] digest = { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
245 				0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1, 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
246 				0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98, 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
247 				0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec, 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 };
248 			HMAC hmac = new SelectableHmacSha512 (key, false);
249 			Check ("HMACSHA512-N-RFC4231-TC6", hmac, data, digest);
250 		}
251 
252 		[Test]
253 		// Test with a key and data that is larger than 128 bytes (= block-size of SHA-384 and SHA-512).
RFC4231_TC7_Normal()254 		public void RFC4231_TC7_Normal ()
255 		{
256 			byte[] key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
257 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
258 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
259 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
260 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
261 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
262 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
263 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
264 				0xaa, 0xaa, 0xaa };
265 			byte[] data = Encoding.Default.GetBytes ("This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.");
266 			byte[] digest = { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
267 				0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86, 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
268 				0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1, 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
269 				0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60, 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 };
270 			HMAC hmac = new SelectableHmacSha512 (key, false);
271 			Check ("HMACSHA512-N-RFC4231-TC7", hmac, data, digest);
272 		}
273 
274 		[Test]
RFC4231_TC1_Legacy()275 		public void RFC4231_TC1_Legacy ()
276 		{
277 			byte[] key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
278 			byte[] data = Encoding.Default.GetBytes ("Hi There");
279 			byte[] digest = { 0x96, 0x56, 0x97, 0x5E, 0xE5, 0xDE, 0x55, 0xE7, 0x5F, 0x29, 0x76, 0xEC, 0xCE, 0x9A, 0x04, 0x50,
280 				0x10, 0x60, 0xB9, 0xDC, 0x22, 0xA6, 0xED, 0xA2, 0xEA, 0xEF, 0x63, 0x89, 0x66, 0x28, 0x01, 0x82,
281 				0x47, 0x7F, 0xE0, 0x9F, 0x08, 0x0B, 0x2B, 0xF5, 0x64, 0x64, 0x9C, 0xAD, 0x42, 0xAF, 0x86, 0x07,
282 				0xA2, 0xBD, 0x8D, 0x02, 0x97, 0x9D, 0xF3, 0xA9, 0x80, 0xF1, 0x5E, 0x23, 0x26, 0xA0, 0xA2, 0x2A };
283 			HMAC hmac = new SelectableHmacSha512 (key, true);
284 			Check ("HMACSHA512-L-RFC4231-TC1", hmac, data, digest);
285 		}
286 
287 		[Test]
288 		// Test with a key shorter than the length of the HMAC output.
RFC4231_TC2_Legacy()289 		public void RFC4231_TC2_Legacy ()
290 		{
291 			byte[] key = Encoding.Default.GetBytes ("Jefe");
292 			byte[] data = Encoding.Default.GetBytes ("what do ya want for nothing?");
293 			byte[] digest = { 0xD2, 0x76, 0x6E, 0xCA, 0x33, 0xFE, 0x85, 0x2B, 0xD6, 0x29, 0x25, 0x3F, 0xE0, 0x1C, 0x63, 0x51,
294 				0x9E, 0xB2, 0x45, 0x9B, 0xDB, 0x0A, 0xF2, 0x54, 0xBD, 0x43, 0x41, 0x74, 0x0B, 0x4D, 0x0E, 0xA7,
295 				0x23, 0xC6, 0xA2, 0xA4, 0xDF, 0xC3, 0x42, 0x52, 0x89, 0x1C, 0x14, 0xF2, 0x65, 0x80, 0x55, 0x23,
296 				0x7A, 0xA3, 0xF6, 0x49, 0x62, 0xD4, 0xD4, 0xDE, 0x21, 0x70, 0xAE, 0x18, 0xFD, 0x91, 0x60, 0xAA };
297 			HMAC hmac = new SelectableHmacSha512 (key, true);
298 			Check ("HMACSHA512-L-RFC4231-TC2", hmac, data, digest);
299 		}
300 
301 		[Test]
302 		// Test with a combined length of key and data that is larger than 64 bytes (= block-size of SHA-224 and SHA-256).
RFC4231_TC3_Legacy()303 		public void RFC4231_TC3_Legacy ()
304 		{
305 			byte[] key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
306 			byte[] data = { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
307 				0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
308 				0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
309 				0xdd, 0xdd };
310 			byte[] digest = { 0x57, 0xD1, 0xE0, 0xB1, 0x1E, 0xE0, 0x8D, 0xF8, 0x9E, 0x3C, 0xDC, 0xD4, 0xB7, 0xD3, 0xA9, 0x2C,
311 				0x42, 0x30, 0x75, 0x24, 0xDB, 0x89, 0xD0, 0xC3, 0x1A, 0xCA, 0xBD, 0x41, 0x58, 0xF5, 0x19, 0xAA,
312 				0xC2, 0x2E, 0x0C, 0xA5, 0xBF, 0x05, 0x37, 0xF1, 0x0B, 0xD8, 0x3B, 0xDE, 0x43, 0x07, 0xD6, 0x4D,
313 				0xE1, 0x91, 0xA2, 0xCF, 0x12, 0x01, 0x8F, 0x49, 0x95, 0x1C, 0xF5, 0x99, 0xFF, 0x8A, 0xD1, 0x68 };
314 			HMAC hmac = new SelectableHmacSha512 (key, true);
315 			Check ("HMACSHA512-L-RFC4231-TC3", hmac, data, digest);
316 		}
317 
318 		[Test]
319 		// Test with a combined length of key and data that is larger than 64 bytes (= block-size of SHA-224 and SHA-256).
RFC4231_TC4_Legacy()320 		public void RFC4231_TC4_Legacy ()
321 		{
322 			byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
323 				0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 };
324 			byte[] data = { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
325 				0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
326 				0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
327 				0xcd, 0xcd };
328 			byte[] digest = { 0xF9, 0x82, 0x79, 0x3A, 0x2E, 0x24, 0xF6, 0xEB, 0x82, 0xF5, 0x2D, 0x10, 0x85, 0x2C, 0x13, 0x50,
329 				0x69, 0xA5, 0x81, 0x99, 0xF8, 0x1C, 0x2E, 0x09, 0x4F, 0xED, 0x96, 0x4E, 0x59, 0xD5, 0x57, 0xE4,
330 				0xE1, 0x02, 0x9A, 0x62, 0x9A, 0xF3, 0x45, 0x8C, 0xA8, 0xEE, 0x8A, 0xB4, 0x39, 0x99, 0x32, 0xE8,
331 				0xC7, 0x94, 0x4B, 0x37, 0xB5, 0x5E, 0x3C, 0xE8, 0xF5, 0x6D, 0x31, 0xA5, 0x25, 0x11, 0x97, 0xFB };
332 			HMAC hmac = new SelectableHmacSha512 (key, true);
333 			Check ("HMACSHA512-L-RFC4231-TC4", hmac, data, digest);
334 		}
335 
336 		[Test]
337 		// Test with a truncation of output to 128 bits.
RFC4231_TC5_Legacy()338 		public void RFC4231_TC5_Legacy ()
339 		{
340 			byte[] key = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
341 				0x0c, 0x0c, 0x0c, 0x0c };
342 			byte[] data = Encoding.Default.GetBytes ("Test With Truncation");
343 			byte[] digest = { 0xBC, 0x59, 0x5A, 0x3F, 0x08, 0x9B, 0x2C, 0x5E, 0x25, 0x9B, 0x94, 0xAD, 0x7C, 0x48, 0xBA, 0xF3 };
344 			HMAC hmac = new SelectableHmacSha512 (key, true);
345 			Check ("HMACSHA512-L-RFC4231-TC5", hmac, data, digest);
346 		}
347 
348 		[Test]
349 		// Test with a key larger than 128 bytes (= block-size of SHA-384 and SHA-512).
RFC4231_TC6_Legacy()350 		public void RFC4231_TC6_Legacy ()
351 		{
352 			byte[] key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
353 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
354 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
355 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
356 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
357 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
358 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
359 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
360 				0xaa, 0xaa, 0xaa };
361 			byte[] data = Encoding.Default.GetBytes ("Test Using Larger Than Block-Size Key - Hash Key First");
362 			byte[] digest = { 0x6A, 0x2D, 0x1C, 0x4B, 0x7B, 0x7A, 0x88, 0x15, 0xBA, 0xC4, 0xEB, 0x5D, 0x41, 0xB6, 0x6F, 0x7F,
363 				0x55, 0x5D, 0x4A, 0xDF, 0x00, 0xD2, 0x83, 0x3F, 0xDF, 0xCD, 0x2B, 0x55, 0xF4, 0xC5, 0x3D, 0xCA,
364 				0xEB, 0x11, 0x86, 0xEE, 0xB6, 0x46, 0x67, 0xB2, 0x54, 0x48, 0x42, 0x94, 0x41, 0x83, 0x57, 0x8E,
365 				0x47, 0xCB, 0x73, 0x32, 0x32, 0x0B, 0x35, 0x4F, 0xC0, 0xD5, 0x19, 0xFF, 0x4E, 0x5D, 0x90, 0xAD };
366 			HMAC hmac = new SelectableHmacSha512 (key, true);
367 			Check ("HMACSHA512-L-RFC4231-TC6", hmac, data, digest);
368 		}
369 
370 		[Test]
371 		// Test with a key and data that is larger than 128 bytes (= block-size of SHA-384 and SHA-512).
RFC4231_TC7_Legacy()372 		public void RFC4231_TC7_Legacy ()
373 		{
374 			byte[] key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
375 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
376 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
377 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
378 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
379 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
380 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
381 				0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
382 				0xaa, 0xaa, 0xaa };
383 			byte[] data = Encoding.Default.GetBytes ("This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.");
384 			byte[] digest = { 0x18, 0xDC, 0x82, 0xB6, 0x9D, 0x9A, 0xF8, 0xA5, 0x28, 0x46, 0x8C, 0x38, 0x3A, 0x99, 0xAB, 0x2E,
385 				0xD4, 0x11, 0x14, 0xA6, 0xBB, 0x24, 0x00, 0x61, 0x13, 0xAA, 0xD2, 0x44, 0x00, 0x5F, 0xA9, 0xC3,
386 				0xAC, 0xBE, 0x53, 0x77, 0xB9, 0x3B, 0x4C, 0x5D, 0x17, 0x16, 0x8C, 0xAA, 0x85, 0x77, 0x52, 0x72,
387 				0xFF, 0xF4, 0x5A, 0xFC, 0x68, 0xF8, 0x90, 0x27, 0x2F, 0x2E, 0x12, 0x9D, 0x81, 0xB6, 0x48, 0x49 };
388 			HMAC hmac = new SelectableHmacSha512 (key, true);
389 			Check ("HMACSHA512-L-RFC4231-TC7", hmac, data, digest);
390 		}
391 
392 		[Test]
Bug6510a()393 		public void Bug6510a ()
394 		{
395 			byte[] key = Encoding.UTF8.GetBytes ("CA61A777DC1041B2FDCC354820F7F83CE0530C0E019A29BF576F175D314A6D891B35F");
396 			byte[] data = Encoding.UTF8.GetBytes ("123456789");
397 			byte[] digest = { 147, 50, 79, 211, 70, 90, 205, 252, 100, 25, 50, 209, 254, 157,
398 				154, 12, 132, 205, 113, 59, 97, 216, 252, 94, 43, 126, 207, 140, 137, 60, 227,
399 				82, 82, 240, 9, 15, 166, 167, 110, 85, 217, 245, 250, 169, 189, 138, 55, 197,
400 				146, 192, 96, 20, 249, 95, 130, 163, 147, 82, 71, 244, 139, 76, 45, 75 };
401 			HMAC hmac = new SelectableHmacSha512 (key, false);
402 			Check ("HMACSHA512-BUG-6510", hmac, data, digest);
403 		}
404 
405 		[Test]
Bug6510b()406 		public void Bug6510b ()
407 		{
408 			byte[] key = Encoding.UTF8.GetBytes ("CA61A777DC1041B2FDCC354820F7F83CE0530C0E019A29BF576F175D314A6D891");
409 			byte[] data = Encoding.UTF8.GetBytes ("123456789");
410 			byte[] digest = { 254, 159, 56, 218, 66, 110, 74, 135, 209, 81, 166, 150, 241, 194,
411 				171, 228, 143, 228, 16, 198, 171, 53, 40, 211, 229, 160, 158, 2, 102, 99, 11,
412 				49, 70, 53, 70, 32, 32, 219, 119, 14, 2, 149, 197, 220, 166, 38, 128, 25, 255,
413 				227, 25, 20, 229, 54, 217, 57, 143, 224, 251, 1, 202, 24, 245, 133 };
414 			HMAC hmac = new SelectableHmacSha512 (key, false);
415 			Check ("HMACSHA512-BUG-6510", hmac, data, digest);
416 		}
417 	}
418 }