cryptography ip-cores in vhdl / verilog
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

428 lines
15 KiB

  1. -- ======================================================================
  2. -- DES encryption/decryption testbench
  3. -- tests according to NIST 800-17 special publication
  4. -- Copyright (C) 2011 Torsten Meissner
  5. -------------------------------------------------------------------------
  6. -- This program is free software; you can redistribute it and/or modify
  7. -- it under the terms of the GNU General Public License as published by
  8. -- the Free Software Foundation; either version 2 of the License, or
  9. -- (at your option) any later version.
  10. -- This program is distributed in the hope that it will be useful,
  11. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. -- GNU General Public License for more details.
  14. -- You should have received a copy of the GNU General Public License
  15. -- along with this program; if not, write to the Free Software
  16. -- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. -- ======================================================================
  18. library ieee;
  19. use ieee.std_logic_1164.all;
  20. use ieee.numeric_std.all;
  21. library osvvm;
  22. use osvvm.RandomPkg.all;
  23. use std.env.all;
  24. use work.des_pkg.all;
  25. use work.tb_des_pkg.all;
  26. entity tb_des is
  27. end entity tb_des;
  28. architecture rtl of tb_des is
  29. signal s_reset : std_logic := '0';
  30. signal s_clk : std_logic := '0';
  31. signal s_mode : std_logic := '0';
  32. signal s_key : std_logic_vector(0 to 63) := (others => '0');
  33. signal s_datain : std_logic_vector(0 to 63) := (others => '0');
  34. signal s_validin : std_logic := '0';
  35. signal s_acceptout : std_logic;
  36. signal s_dataout : std_logic_vector(0 to 63);
  37. signal s_validout : std_logic;
  38. signal s_acceptin : std_logic;
  39. procedure cryptData(datain : in std_logic_vector(0 to 63);
  40. key : in std_logic_vector(0 to 63);
  41. mode : in boolean;
  42. dataout : out std_logic_vector(0 to 63);
  43. bytelen : in integer) is
  44. begin
  45. report "VHPIDIRECT cryptData" severity failure;
  46. end procedure;
  47. attribute foreign of cryptData: procedure is "VHPIDIRECT cryptData";
  48. function swap (datain : std_logic_vector(0 to 63)) return std_logic_vector is
  49. variable v_data : std_logic_vector(0 to 63);
  50. begin
  51. for i in 0 to 7 loop
  52. for y in 0 to 7 loop
  53. v_data((i*8)+y) := datain((i*8)+7-y);
  54. end loop;
  55. end loop;
  56. return v_data;
  57. end function;
  58. begin
  59. s_clk <= not(s_clk) after 10 ns;
  60. s_reset <= '1' after 100 ns;
  61. testP : process is
  62. variable v_key : std_logic_vector(0 to 63);
  63. variable v_datain : std_logic_vector(0 to 63);
  64. variable v_dataout : std_logic_vector(0 to 63);
  65. variable v_plaintext : std_logic_vector(0 to 63) := x"8000000000000000";
  66. variable v_random : RandomPType;
  67. begin
  68. -- ENCRYPTION TESTS
  69. s_validin <= '0';
  70. s_acceptin <= '0';
  71. s_mode <= '0';
  72. s_datain <= (others => '0');
  73. s_key <= (others => '0');
  74. wait until s_reset = '1';
  75. report "# ENCRYPTION TESTS";
  76. -- Variable plaintext known answer test
  77. report "# Variable plaintext known answer test";
  78. v_key := x"0101010101010101";
  79. v_datain := x"8000000000000000";
  80. for index in c_variable_plaintext_known_answers'range loop
  81. wait until rising_edge(s_clk);
  82. s_validin <= '1';
  83. s_key <= v_key;
  84. s_datain <= v_datain;
  85. cryptData(swap(v_datain), swap(v_key), true, v_dataout, v_datain'length/8);
  86. wait until rising_edge(s_clk) and s_acceptout = '1';
  87. s_validin <= '0';
  88. wait until rising_edge(s_clk) and s_validout = '1';
  89. s_acceptin <= '1';
  90. assert s_dataout = c_variable_plaintext_known_answers(index)
  91. report "Encryption error"
  92. severity failure;
  93. assert s_dataout = swap(v_dataout)
  94. report "Encryption openSSL reference error"
  95. severity failure;
  96. wait until rising_edge(s_clk);
  97. s_acceptin <= '0';
  98. v_datain := '0' & v_datain(0 to 62);
  99. end loop;
  100. -- Inverse permutation known answer test
  101. report "# Inverse permutation known answer test";
  102. v_key := x"0101010101010101";
  103. for index in c_variable_plaintext_known_answers'range loop
  104. v_datain := c_variable_plaintext_known_answers(index);
  105. s_validin <= '1';
  106. s_key <= v_key;
  107. s_datain <= v_datain;
  108. cryptData(swap(v_datain), swap(v_key), true, v_dataout, v_datain'length/8);
  109. wait until rising_edge(s_clk) and s_acceptout = '1';
  110. s_validin <= '0';
  111. wait until rising_edge(s_clk) and s_validout = '1';
  112. s_acceptin <= '1';
  113. assert s_dataout = v_plaintext
  114. report "Encryption error"
  115. severity failure;
  116. assert s_dataout = swap(v_dataout)
  117. report "Encryption openSSL reference error"
  118. severity failure;
  119. wait until rising_edge(s_clk);
  120. s_acceptin <= '0';
  121. v_plaintext := '0' & v_plaintext(0 to 62);
  122. end loop;
  123. -- Variable key known answer test
  124. report "# Variable key known answer test";
  125. v_key := x"8000000000000000";
  126. v_datain := (others => '0');
  127. for index in c_variable_key_known_answers'range loop
  128. s_validin <= '1';
  129. s_key <= v_key;
  130. s_datain <= v_datain;
  131. cryptData(swap(v_datain), swap(v_key), true, v_dataout, v_datain'length/8);
  132. wait until rising_edge(s_clk) and s_acceptout = '1';
  133. s_validin <= '0';
  134. wait until rising_edge(s_clk) and s_validout = '1';
  135. s_acceptin <= '1';
  136. assert s_dataout = c_variable_key_known_answers(index)
  137. report "Encryption error"
  138. severity failure;
  139. assert s_dataout = swap(v_dataout)
  140. report "Encryption openSSL reference error"
  141. severity failure;
  142. wait until rising_edge(s_clk);
  143. s_acceptin <= '0';
  144. if (index = 6 or index = 13 or index = 20 or index = 27 or index = 34 or
  145. index = 41 or index = 48) then
  146. v_key := "00" & v_key(0 to 61);
  147. else
  148. v_key := '0' & v_key(0 to 62);
  149. end if;
  150. end loop;
  151. -- Permutation operation known answer test
  152. report "# Permutation operation known answer test";
  153. v_datain := (others => '0');
  154. for index in c_permutation_operation_known_answers_keys'range loop
  155. wait until rising_edge(s_clk);
  156. v_key := c_permutation_operation_known_answers_keys(index);
  157. s_validin <= '1';
  158. s_key <= v_key;
  159. s_datain <= v_datain;
  160. cryptData(swap(v_datain), swap(v_key), true, v_dataout, v_datain'length/8);
  161. wait until rising_edge(s_clk) and s_acceptout = '1';
  162. s_validin <= '0';
  163. wait until rising_edge(s_clk) and s_validout = '1';
  164. s_acceptin <= '1';
  165. assert s_dataout = c_permutation_operation_known_answers_cipher(index)
  166. report "Encryption error"
  167. severity failure;
  168. assert s_dataout = swap(v_dataout)
  169. report "Encryption openSSL reference error"
  170. severity failure;
  171. wait until rising_edge(s_clk);
  172. s_acceptin <= '0';
  173. end loop;
  174. -- Substitution table known answer test
  175. report "# Substitution table known answer test";
  176. for index in c_substitution_table_test_keys'range loop
  177. wait until rising_edge(s_clk);
  178. v_key := c_substitution_table_test_keys(index);
  179. v_datain := c_substitution_table_test_plain(index);
  180. s_validin <= '1';
  181. s_key <= v_key;
  182. s_datain <= v_datain;
  183. cryptData(swap(v_datain), swap(v_key), true, v_dataout, v_datain'length/8);
  184. wait until rising_edge(s_clk) and s_acceptout = '1';
  185. s_validin <= '0';
  186. wait until rising_edge(s_clk) and s_validout = '1';
  187. s_acceptin <= '1';
  188. assert s_dataout = c_substitution_table_test_cipher(index)
  189. report "Encryption error"
  190. severity failure;
  191. assert s_dataout = swap(v_dataout)
  192. report "Encryption openSSL reference error"
  193. severity failure;
  194. wait until rising_edge(s_clk);
  195. s_acceptin <= '0';
  196. end loop;
  197. -- Random key & data openSSL reference test
  198. report "# Random key & data openSSL reference test";
  199. for index in 0 to 63 loop
  200. wait until rising_edge(s_clk);
  201. v_key := v_random.RandSlv(64);
  202. v_datain := v_random.RandSlv(64);
  203. s_validin <= '1';
  204. s_key <= v_key;
  205. s_datain <= v_datain;
  206. cryptData(swap(v_datain), swap(v_key), true, v_dataout, v_datain'length/8);
  207. wait until rising_edge(s_clk) and s_acceptout = '1';
  208. s_validin <= '0';
  209. wait until rising_edge(s_clk) and s_validout = '1';
  210. s_acceptin <= '1';
  211. assert s_dataout = swap(v_dataout)
  212. report "Encryption openSSL reference error"
  213. severity failure;
  214. wait until rising_edge(s_clk);
  215. s_acceptin <= '0';
  216. end loop;
  217. -- DECRYPTION TESTS
  218. report "# DECRYPTION TESTS";
  219. s_mode <= '1';
  220. -- Variable ciphertext known answer test
  221. report "# Variable ciphertext known answer test";
  222. v_key := x"0101010101010101";
  223. v_plaintext := x"8000000000000000";
  224. for index in c_variable_plaintext_known_answers'range loop
  225. wait until rising_edge(s_clk);
  226. v_datain := c_variable_plaintext_known_answers(index);
  227. s_validin <= '1';
  228. s_key <= v_key;
  229. s_datain <= v_datain;
  230. cryptData(swap(v_datain), swap(v_key), false, v_dataout, v_datain'length/8);
  231. wait until rising_edge(s_clk) and s_acceptout = '1';
  232. s_validin <= '0';
  233. wait until rising_edge(s_clk) and s_validout = '1';
  234. s_acceptin <= '1';
  235. assert s_dataout = v_plaintext
  236. report "Encryption error"
  237. severity failure;
  238. assert s_dataout = swap(v_dataout)
  239. report "Encryption openSSL reference error"
  240. severity failure;
  241. wait until rising_edge(s_clk);
  242. s_acceptin <= '0';
  243. v_plaintext := '0' & v_plaintext(0 to 62);
  244. end loop;
  245. -- Initial permutation known answer test
  246. report "# Initial permutation known answer test";
  247. v_key := x"0101010101010101";
  248. v_datain := x"8000000000000000";
  249. for index in c_variable_plaintext_known_answers'range loop
  250. wait until rising_edge(s_clk);
  251. s_validin <= '1';
  252. s_key <= v_key;
  253. s_datain <= v_datain;
  254. cryptData(swap(v_datain), swap(v_key), false, v_dataout, v_datain'length/8);
  255. wait until rising_edge(s_clk) and s_acceptout = '1';
  256. s_validin <= '0';
  257. wait until rising_edge(s_clk) and s_validout = '1';
  258. s_acceptin <= '1';
  259. assert s_dataout = c_variable_plaintext_known_answers(index)
  260. report "Encryption error"
  261. severity failure;
  262. assert s_dataout = swap(v_dataout)
  263. report "Encryption openSSL reference error"
  264. severity failure;
  265. wait until rising_edge(s_clk);
  266. s_acceptin <= '0';
  267. v_datain := '0' & v_datain(0 to 62);
  268. end loop;
  269. -- Variable key known answer test
  270. report "# Variable key known answer test";
  271. v_key := x"8000000000000000";
  272. for index in c_variable_key_known_answers'range loop
  273. v_datain := c_variable_key_known_answers(index);
  274. s_validin <= '1';
  275. s_key <= v_key;
  276. s_datain <= v_datain;
  277. cryptData(swap(v_datain), swap(v_key), false, v_dataout, v_datain'length/8);
  278. wait until rising_edge(s_clk) and s_acceptout = '1';
  279. s_validin <= '0';
  280. wait until rising_edge(s_clk) and s_validout = '1';
  281. s_acceptin <= '1';
  282. assert s_dataout = 64x"0"
  283. report "Encryption error"
  284. severity failure;
  285. assert s_dataout = swap(v_dataout)
  286. report "Encryption openSSL reference error"
  287. severity failure;
  288. wait until rising_edge(s_clk);
  289. s_acceptin <= '0';
  290. if (index = 6 or index = 13 or index = 20 or index = 27 or index = 34 or
  291. index = 41 or index = 48) then
  292. v_key := "00" & v_key(0 to 61);
  293. else
  294. v_key := '0' & v_key(0 to 62);
  295. end if;
  296. end loop;
  297. -- Permutation operation known answer test
  298. report "# Permutation operation known answer test";
  299. v_datain := (others => '0');
  300. for index in c_permutation_operation_known_answers_keys'range loop
  301. wait until rising_edge(s_clk);
  302. v_key := c_permutation_operation_known_answers_keys(index);
  303. v_datain := c_permutation_operation_known_answers_cipher(index);
  304. s_validin <= '1';
  305. s_key <= v_key;
  306. s_datain <= v_datain;
  307. cryptData(swap(v_datain), swap(v_key), false, v_dataout, v_datain'length/8);
  308. wait until rising_edge(s_clk) and s_acceptout = '1';
  309. s_validin <= '0';
  310. wait until rising_edge(s_clk) and s_validout = '1';
  311. s_acceptin <= '1';
  312. assert s_dataout = 64x"0"
  313. report "Encryption error"
  314. severity failure;
  315. assert s_dataout = swap(v_dataout)
  316. report "Encryption openSSL reference error"
  317. severity failure;
  318. wait until rising_edge(s_clk);
  319. s_acceptin <= '0';
  320. end loop;
  321. -- Substitution table known answer test
  322. report "# Substitution table known answer test";
  323. for index in c_substitution_table_test_keys'range loop
  324. wait until rising_edge(s_clk);
  325. v_key := c_substitution_table_test_keys(index);
  326. v_datain := c_substitution_table_test_cipher(index);
  327. s_validin <= '1';
  328. s_key <= v_key;
  329. s_datain <= v_datain;
  330. cryptData(swap(v_datain), swap(v_key), false, v_dataout, v_datain'length/8);
  331. wait until rising_edge(s_clk) and s_acceptout = '1';
  332. s_validin <= '0';
  333. wait until rising_edge(s_clk) and s_validout = '1';
  334. s_acceptin <= '1';
  335. assert s_dataout = c_substitution_table_test_plain(index)
  336. report "Encryption error"
  337. severity failure;
  338. assert s_dataout = swap(v_dataout)
  339. report "Encryption openSSL reference error"
  340. severity failure;
  341. wait until rising_edge(s_clk);
  342. s_acceptin <= '0';
  343. end loop;
  344. -- Random key & data openSSL reference test
  345. report "# Random key & data openSSL reference test";
  346. for index in 0 to 63 loop
  347. wait until rising_edge(s_clk);
  348. v_key := v_random.RandSlv(64);
  349. v_datain := v_random.RandSlv(64);
  350. s_validin <= '1';
  351. s_key <= v_key;
  352. s_datain <= v_datain;
  353. cryptData(swap(v_datain), swap(v_key), false, v_dataout, v_datain'length/8);
  354. wait until rising_edge(s_clk) and s_acceptout = '1';
  355. s_validin <= '0';
  356. wait until rising_edge(s_clk) and s_validout = '1';
  357. s_acceptin <= '1';
  358. assert s_dataout = swap(v_dataout)
  359. report "Encryption openSSL reference error"
  360. severity failure;
  361. wait until rising_edge(s_clk);
  362. s_acceptin <= '0';
  363. end loop;
  364. wait for 100 ns;
  365. report "# Successfully passed all tests";
  366. finish(0);
  367. wait;
  368. end process testP;
  369. i_des : des
  370. generic map (
  371. design_type => "ITER"
  372. )
  373. port map (
  374. reset_i => s_reset,
  375. clk_i => s_clk,
  376. mode_i => s_mode,
  377. key_i => s_key,
  378. data_i => s_datain,
  379. valid_i => s_validin,
  380. accept_o => s_acceptout,
  381. data_o => s_dataout,
  382. valid_o => s_validout,
  383. accept_i => s_acceptin
  384. );
  385. end architecture rtl;