1`timescale 1ns / 1ps
2/*
3 * This software is Copyright (c) 2018-2019 Denis Burykin
4 * [denis_burykin yahoo com], [denis-burykin2014 yandex ru]
5 * and it is hereby released to the general public under the following terms:
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted.
8 *
9 */
10
11
12module sha512crypt_test();
13
14	reg READ_ALL_FROM_OUTPUT_FIFO = 0;
15
16	genvar i;
17	integer k, k1, k2;
18	reg [7:0] char;
19
20	reg [7:0] app_mode = 0;
21
22	initial begin
23
24		// *****************************************************************
25		//
26		// Send data packets exactly as they arrive from USB controller.
27		//
28		// Output packets appear in output_fifo.fifo_output0.ram
29		// exactly as before they leave FPGA.
30		// On errors it sets pkt_comm_status and app_status available
31		// via low-speed interface.
32		//
33		// It has no internal check for the count of rounds.
34		//
35		// *****************************************************************
36		#500;
37
38		// *****************************************************************
39		//
40		// Test #1.
41		//
42		// Hash formatted as in reference implementation (sha512crypt.c):
43		//	{ "$6$rounds=10$ssssssss", "11111111",
44		//		"$6$rounds=10$ssssssss$1pzpbYbN3IQuS6xYu0CAfKMVtZmcTyMdI"
45		//		"MufpgJ7uljsKxOPG4F0xKjAQfh9/W6.Edy18.Mt6l1qOmjXFazEy1"	},
46		//
47		// Data packet for computing unit (sha512unit_test.v):
48		// send_data_packet(10,8,8,"ssssssss","11111111");
49		//
50		// Hash (MSB 1st): fe43fc48e5ea812e ... 9fa385ba93c527d7
51		//
52		// *****************************************************************
53
54		// Usage: send_config_packet(subtype,data_len,data);
55		//send_config_packet(1,2,16'b_0000_0001_0000_1100);
56
57		// Usage: cmp_config_create(cnt,salt_len,"salt");
58		cmp_config_create(10,8,"ssssssss");
59		cmp_config_add_hash(32'h93c527d7);
60		send_cmp_config();
61
62		send_empty_word_gen(1);
63
64		word_list_add("keylen7");
65		word_list_add("mypwd123");
66		word_list_add("mypwd1234");
67		word_list_add("mypwd12345");
68		word_list_add("pass_len_is15..");
69
70		//for (k=0; k < 500; k=k+1)
71		for (k=0; k < 30; k=k+1)
72			word_list_add("11111110-b");
73
74		word_list_add("11111111");
75		word_list_add("11111101");
76		word_list_add("11111011");
77
78		send_word_list();
79
80		// *****************************************************************
81		//
82		// Test #2.
83		//
84		//	{ "$6$rounds=101$saltSALTsaltSALT", "salt_len=16, key_len=64, contains 8-bit chars (�����) .........z",
85		//		"$6$rounds=101$saltSALTsaltSALT$Z5uHBwC.vjuBsI5/Iuy0EHx/tVUpAz0F9Lnv"
86		//		"CU2WHPM8BYTzfsQ7KSxnTIfywQxZDZng/rhWx6l5tafzp0wvT." },
87		//
88		// Hash (MSB 1st): 1fefb93d8a393cfa ... ccd6d49404ab0d4f
89		//
90		// *****************************************************************
91/*
92		cmp_config_create(101,16,"saltSALTsaltSALT");
93		// add-up 25 dummy hashes to the comparator
94		for (k=0; k < 25; k=k+1)
95			cmp_config_add_hash(32'h00000100 + k);
96
97		cmp_config_add_hash(32'h04ab0d4f);
98
99		for (k=0; k < 25; k=k+1)
100			cmp_config_add_hash(32'hff000000 + k);
101		send_cmp_config();
102
103		send_empty_word_gen(2);
104
105
106		word_list_add("mypwd123");
107		word_list_add("mypwd12345");
108		word_list_add("11111111");
109		word_list_add({ "0123456789012345678901234567890",
110			8'd192,8'd193,8'd194,8'd195,8'd196 }); // 35 bytes, 8-bit
111
112		word_list_add({ "0123456789012345678901234567890",
113			"12345678901234567890123456789012" }); // 63 bytes
114		word_list_add({ "0123456789012345678901234567890",
115			"123456789012345678901234567890123" }); // 64 bytes
116		word_list_add({ "0123456789012345678901234567890",
117			"12345678901234567890",8'd193,"1234567890" }); // 62 bytes
118		word_list_add({ "0123456789012345678901234567890",
119			"12345678901234567890",8'd192,8'd193,"1234567890" });
120		word_list_add({ "0123456789012345678901234567890",
121			"12345678901234567890",8'd192,8'd193,8'd194,"1234567890" });
122		word_list_add({ "salt_len=16, key_len=64, contains 8-bit chars (",
123			8'd192,8'd193, 8'd194,8'd196,8'd195,") .........z" });
124
125		for (k=0; k < 10; k=k+1) begin
126			char <= 8'd200 + k;
127			word_list_add({ "salt_len=16, key_len=64, contains 8-bit chars (",
128				8'd192,8'd193, 8'd194,8'd195,char,") .........z" });
129		end
130
131		word_list_add({ "salt_len=16, key_len=64, contains 8-bit chars (",
132			8'd192,8'd193, 8'd194,8'd195,8'd196,") .........z" }); // <-- right 1
133		word_list_add({ "salt_len=16, key_len=64, contains 8-bit chars (",
134			8'd192,8'd193, 8'd195,8'd195,8'd196,") .........z" });
135		word_list_add({ "salt_len=16, key_len=64, contains 8-bit chars (",
136			8'd192,8'd193, 8'd194,8'd196,8'd196,") .........z" });
137
138		// 23 candidates total. Running time (on 2 units) --- us.
139		// CMP_RESULT: pkt_id=2, word_id=20, gen_id=0, hash_num=25
140		send_word_list();
141*/
142
143		// *****************************************************************
144		//
145		// Test #3.
146		//
147		// 3 hashes with same salt from John the Ripper, sha512crypt_common.h
148		//
149		//	{"$6$LKO/Ute40T3FNF95$6S/6T2YuOIHY0N3XpLKABJ3soYcXD9mB7uVbtEZDj"
150		//		"/LNscVhZoZ9DEH.sBciDrMsHOWOoASbNLTypH/5X26gN0", "U*U*U*U*"},
151		//	{"$6$LKO/Ute40T3FNF95$wK80cNqkiAUzFuVGxW6eFe8J.fSVI65MD5yEm8EjY"
152		//		"MaJuDrhwe5XXpHDJpwF/kY.afsUs1LlgQAaOapVNbggZ1", "U*U***U"},
153		//	{"$6$LKO/Ute40T3FNF95$YS81pp1uhOHTgKLhSMtQCr2cDiUiN03Ud3gyD4ame"
154		//		"viK1Zqz.w3oXsMgO6LrqmIEcG3hiqaUqHi/WEE2zrZqa/", "U*U***U*"},
155		//
156		// Hashes (MSB 1st):
157		// 99b014d9 9d26cfba ... cf8e55f5 8c351f20
158		// e5b2592c c58a0147 ... 1485aabd 4a036808
159		// 66da04f6 8254b6dd ... 99ba4d1e b536750c
160		//
161		// *****************************************************************
162/*
163		cmp_config_create(5000,16,"LKO/Ute40T3FNF95");
164
165		// We send hashes in ascending order. Currently that doesn't
166		// matter as linear search is implemented.
167		for (k=0; k < 200; k=k+1)
168			cmp_config_add_hash(32'h49000000 + k);
169
170		cmp_config_add_hash(32'h4a0368_00);
171		cmp_config_add_hash(32'h4a0368_28);
172		cmp_config_add_hash(32'h4a0368_18);
173		cmp_config_add_hash(32'h4a0368_08); // <-- the right 1
174		cmp_config_add_hash(32'h4a0368_09);
175
176		for (k=0; k < 200; k=k+1)
177			cmp_config_add_hash(32'h8b000000 + k);
178
179		cmp_config_add_hash(32'h8c351_e20);
180		cmp_config_add_hash(32'h8c351_f20); // <-- the right 1
181		cmp_config_add_hash(32'h8c351_f21);
182		cmp_config_add_hash(32'h8c351_f00);
183		cmp_config_add_hash(32'h8c351_f24);
184
185		for (k=410; k < `NUM_HASHES - 1; k=k+1)
186			cmp_config_add_hash(32'h99001100 + k);
187
188		cmp_config_add_hash(32'hb536750c); // <-- the right 1
189		// Total `NUM_HASHES hashes in CMP_CONFIG
190		send_cmp_config();
191
192
193		// Candidates are split into several packets.
194		// ID from input WORD_GEN packets are used in output packets.
195		// Packet #1 (pkt_id=3).
196		send_empty_word_gen(3);
197
198		word_list_add("mypwd123");
199		word_list_add(""); // 0-length word
200		word_list_add("11111111");
201		for (k=0; k < 27; k=k+1) begin
202			char <= "*" + 1 + k;
203			word_list_add({"U*U*U*U",char});
204		end
205
206		// Must output CMP_RESULT packet (type 0xD4) containing:
207		// 512-bit hash, pkt_id=3, word_id=30, gen_id=0, hash_num=406
208		word_list_add("U*U*U*U*");
209		send_word_list();
210
211
212		// Packet #2 (pkt_id=4), 32 words. Same CMP_CONFIG applies.
213		send_empty_word_gen(4);
214		for (k=0; k < 31; k=k+1) begin
215			char <= "U" - 10 + k;
216			word_list_add({char,"*U***U*"});
217		end
218		word_list_add("U*U***U");
219
220		// Hashes are 5,000 rounds. The test takes time.
221		// Running time (2 units X 4 cores, at 20 ns simulation clock)
222		// is ---.
223		send_word_list();
224*/
225
226		// *****************************************************************
227		//
228		// Test #4.
229		//
230		// Using onboard generator. Hash:
231		//
232		//	{ "$6$rounds=5$1234567", "Pass012",
233		//		"$6$rounds=5$1234567$gzYyIG.wBGAzHp8bNIw69VXJtMkr9cKSi38D9x1VuQz"
234		//		"/JitL1x.1q3y6rqgEHNWa/Z.XGBmHxYK/NIGR3pYgH1" },
235		//
236		// d3b2253d4f095342 .. 9acd760c 9b3a84a1 0bdf3819 9cc494fa
237		//
238		// *****************************************************************
239/*
240		cmp_config_create(5,7,"1234567"); // rounds=5, salt_len=7
241		cmp_config_add_hash(32'h9cc494fa);
242		send_cmp_config();
243
244		word_gen_add_range("012");
245		word_gen_add_range("012");
246		send_word_gen(5);
247
248		// range_info: placeholders in positions 4,5
249		word_list_add("Pass##2"); range_info_add(8'h84,8'h85,0,0);
250		word_list_add("Pass##1"); range_info_add(8'h84,8'h85,0,0);
251		word_list_add("Pass##0"); range_info_add(8'h84,8'h85,0,0);
252		send_word_list();
253*/
254
255		// *****************************************************************
256		//
257		// Test #5.
258		//
259		// Compute, output hashes w/o usage of comparator.
260		// Results appear in PKT_RESULT (type 0xD3) packets.
261		//
262		// *****************************************************************
263/*
264		// It requires to be idle when app_mode changes.
265		// Typically app_mode is set after the GSR and doesn't change
266		// during runtime.
267		//
268		app_mode <= 8'h40;
269		//
270		//	{ "$6$rounds=1$ssssssss", "11111111",
271		//		"$6$rounds=1$ssssssss$qunghpov5q2ivheRC8iomgzuu843t4EsV8"
272		//		"5x5u8JCVeIf.bMqb9qAjQY/NmPxIom8agzWm/W0stDhHbrKtfcZ."	},
273		//
274		//	25a2740288c93d6f ... b914fb8e764d6db3
275		//
276		cmp_config_create(1,8,"ssssssss");
277		//cmp_config_add_hash(32'h4a0368_00);
278		send_cmp_config();
279		send_empty_word_gen(6);
280		word_list_add("11111111");
281		send_word_list();
282
283		//	{ "$6$rounds=51$salt_length13", "",
284		//		"$6$rounds=51$salt_length13$gKRKWpplj6e3.bJ0mbfgbIihDBLHC"
285		//		"LqFQAkyVcWpi1Y6zpsUdTsb9HpuOsIFAT/wQ9ezHVHNnYio6WAe30OUK1" },
286		//
287		// d681c83365a2cc45 ... ce4de5f209a26259
288		//
289		cmp_config_create(51,13,"salt_length13");
290		send_cmp_config();
291		send_empty_word_gen(7);
292		word_list_add("");
293		send_word_list();
294
295		//	{ "$6$rounds=11$salt_len9", "password 16chars",
296		//		"$6$rounds=11$salt_len9$gLFJl32iZRSwMQuyOVLFleb/rooFoP7uZ"
297		//		"W/YgNc/wuG892uVTfCqN.ubNBd0UPFKd4M3UUFyrge345y3KExp2." },
298		//
299		// 04d7e137f981e00a ... f4477a5afbe77155
300		//
301		cmp_config_create(11,9,"salt_len9");
302		send_cmp_config();
303		send_empty_word_gen(8);
304		word_list_add("password 16chars");
305		send_word_list();
306*/
307
308		// *****************************************************************
309		//
310		// Test #6.
311		//
312		// Drupal7 hashes.
313		//
314		// *****************************************************************
315/*
316		// Set Drupal7 program
317		#2000;
318		send_init_packet(1);
319
320		// {"$S$CFURCPa.k6FAEbJPgejaW4nijv7rYgGc4dUJtChQtV4KLJTPTC/u", "password"}
321		cmp_config_create(16384,8,"FURCPa.k");
322		cmp_config_add_hash(32'h6740c448);
323		send_cmp_config();
324
325		send_empty_word_gen(6);
326
327		word_list_add("passwor-");
328		word_list_add("password");
329		word_list_add("passwor");
330		send_word_list();
331*/
332	end
333
334
335
336	// ***************************************************************
337	//
338	//
339	//
340	// ***************************************************************
341	reg PKT_COMM_CLK = 0, IFCLK = 0, CORE_CLK = 0;
342
343	//wire CORE_CLK = PKT_COMM_CLK;
344
345	reg [7:0] din;
346	reg wr_en = 0;
347
348`include "../pkt_comm/pkt_comm_test_helper.vh"
349
350
351	// ***************************************************************
352	//
353	// Simulating input via USB controller, FPGA's Input fifo
354	//
355	// ***************************************************************
356	wire [15:0] app_dout;
357	wire [7:0] app_status, pkt_comm_status, debug2, debug3;
358	wire [7:0] hs_input_dout;
359
360	fifo_sync_small #( .A_WIDTH(16), .D_WIDTH(8)
361	) fifo_input1(
362		.CLK(PKT_COMM_CLK),
363		.din(din),
364		.wr_en(wr_en),
365		.full(),
366
367		.dout(hs_input_dout),
368		.rd_en(hs_input_rd_en),
369		.empty(hs_input_empty)
370	);
371
372	sha512crypt #(.DISABLE_CHECKSUM(1)) pkt_comm(
373	//pkt_comm_v2 pkt_comm(
374		.PKT_COMM_CLK(PKT_COMM_CLK),
375		.CORE_CLK(CORE_CLK),
376		// High-Speed FPGA input
377		.din(hs_input_dout),
378		.rd_en(hs_input_rd_en),
379		.empty(hs_input_empty),
380		// High-Speed FPGA output
381		.dout(app_dout),
382		.wr_en(app_wr_en),
383		.full(app_full),
384		// Application control (via VCR I/O). Set with fpga_set_app_mode()
385		.app_mode(app_mode),
386		// Application status. Available at fpga->wr.io_state.app_status
387		.cores_idle(cores_idle),
388		.app_status(app_status), .pkt_comm_status(pkt_comm_status),
389		.debug2(debug2), .debug3(debug3)
390	);
391
392
393	// ********************************************************
394	//
395	// Output buffer (via High-Speed interface)
396	//
397	// ********************************************************
398	output_fifo output_fifo(
399		.wr_clk(PKT_COMM_CLK),
400		.din(app_dout),
401		.wr_en(app_wr_en),
402		.full(app_full),
403
404		.rd_clk(IFCLK),
405		.dout(), // to Cypress IO,
406		.rd_en(READ_ALL_FROM_OUTPUT_FIFO), // to Cypress IO,
407		.empty(), // to Cypress IO
408		.mode_limit(1'b1),
409		.reg_output_limit(READ_ALL_FROM_OUTPUT_FIFO),
410		.output_limit(),
411		.output_limit_not_done()
412	);
413
414
415	// This does not reflect actual timing
416	initial begin
417		#3;
418		while (1) begin
419			CORE_CLK <= ~CORE_CLK; #6;
420		end
421	end
422
423	initial begin
424		#5;
425		while (1) begin
426			PKT_COMM_CLK <= ~PKT_COMM_CLK; #10;
427		end
428	end
429
430	initial begin
431		#35;
432		while (1) begin
433			IFCLK <= ~IFCLK; #70;
434		end
435	end
436
437endmodule
438