1 |
2 |
jdoin |
----------------------------------------------------------------------------------
|
2 |
6 |
jdoin |
-- Author: Jonny Doin, jdoin@opencores.org, jonnydoin@gmail.com, jonnydoin@gridvortex.com
|
3 |
2 |
jdoin |
--
|
4 |
6 |
jdoin |
-- Create Date: 01:21:32 05/05/2016
|
5 |
2 |
jdoin |
-- Design Name: gv_sha256
|
6 |
|
|
-- Module Name: GV_SHA256 toplevel
|
7 |
|
|
-- Project Name: GV_SHA256 engine
|
8 |
|
|
-- Target Devices: Spartan-6 LX45
|
9 |
|
|
-- Tool versions: ISE 14.7
|
10 |
|
|
-- Description:
|
11 |
|
|
--
|
12 |
|
|
-- This is the gv_sha256 engine top level.
|
13 |
|
|
-- The gv_sha256 is a stream hash engine, i.e., the data words are hashed as a stream of words read from an input bus, with
|
14 |
|
|
-- control inputs for BEGIN/END of the message data stream. The input bus is a 32bit word bus, with a byte lane selector to signalize
|
15 |
|
|
-- how many bytes are valid in the last word.
|
16 |
|
|
--
|
17 |
10 |
jdoin |
-- The core is a structural integration of the logic blocks for the SHA256 engine, with the internal datapath and controlpath wires.
|
18 |
2 |
jdoin |
--
|
19 |
|
|
-- Written in synthesizable VHDL, the hash engine is a low resource, area-efficient implementation of the FIPS-180-4 SHA256 hash algorithm.
|
20 |
|
|
-- Designed around the core registers and combinational hash functions as a 768bit-wide engine, the engine takes 64+1 clocks to
|
21 |
|
|
-- compute a hash block.
|
22 |
|
|
--
|
23 |
|
|
-- It is designed for stand-alone ASIC functions and 32-bit bus interfaces for generic processor integration.
|
24 |
|
|
--
|
25 |
|
|
-- The data input port is organized as a 32bit word write register, with flow control and begin/end signals.
|
26 |
|
|
-- The 256bit result register is organized as 8 x 32bit registers that can be read simultaneously.
|
27 |
|
|
--
|
28 |
|
|
-- This implementation is a conservative implementation of the approved FIPS-180-4 algorithm, with a fair compromise of resources,
|
29 |
|
|
-- comprising of only 32 registers of 32bit words for the hash engine, with a single-cycle combinational logic for each algorithm step.
|
30 |
|
|
-- The combinational logic depth of the engine is 10 logic layers. For a process with 650ps of average (Tpd + Tsu), this core can
|
31 |
|
|
-- be synthesized to 75MHz system clock.
|
32 |
|
|
--
|
33 |
|
|
-- The GV_SHA256 is a basic cryptographic block, used by almost all encryption and digital signature schemes.
|
34 |
|
|
--
|
35 |
|
|
-- Applications include low-cost CyberPhysical Systems and also fast backend crypto functions for realtime hashing of packet data.
|
36 |
|
|
-- It is used in the GridVortex CyberSec IP, as a base for the fused HMAC-SHA256, HKDF, HMAC-SHA256-DRBG, and the SP-800 TRNG Entropy Source.
|
37 |
|
|
--
|
38 |
|
|
------------------------------ COPYRIGHT NOTICE -----------------------------------------------------------------------
|
39 |
9 |
jdoin |
--
|
40 |
|
|
-- This file is part of the SHA256 HASH CORE project http://opencores.org/project,sha256_hash_core
|
41 |
|
|
--
|
42 |
|
|
-- Author(s): Jonny Doin, jdoin@opencores.org, jonnydoin@gridvortex.com, jonnydoin@gmail.com
|
43 |
|
|
--
|
44 |
|
|
-- Copyright (C) 2016 Jonny Doin
|
45 |
|
|
-- -----------------------------
|
46 |
|
|
--
|
47 |
|
|
-- This source file may be used and distributed without restriction provided that this copyright statement is not
|
48 |
|
|
-- removed from the file and that any derivative work contains the original copyright notice and the associated
|
49 |
|
|
-- disclaimer.
|
50 |
|
|
--
|
51 |
|
|
-- This source file is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
|
52 |
|
|
-- General Public License as published by the Free Software Foundation; either version 2.1 of the License, or
|
53 |
|
|
-- (at your option) any later version.
|
54 |
|
|
--
|
55 |
|
|
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
56 |
|
|
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
57 |
|
|
-- details.
|
58 |
|
|
--
|
59 |
|
|
-- You should have received a copy of the GNU Lesser General Public License along with this source; if not, download
|
60 |
|
|
-- it from http://www.gnu.org/licenses/lgpl.txt
|
61 |
|
|
--
|
62 |
2 |
jdoin |
------------------------------ REVISION HISTORY -----------------------------------------------------------------------
|
63 |
|
|
--
|
64 |
|
|
-- 2016/05/22 v0.01.0010 [JD] started development. design of blocks and port interfaces.
|
65 |
|
|
-- 2016/06/05 v0.01.0090 [JD] all modules integrated. testbench for basic test vectors verification.
|
66 |
|
|
-- 2016/06/05 v0.01.0095 [JD] verification failed. misalignment of words in the datapath.
|
67 |
|
|
-- 2016/06/06 v0.01.0100 [JD] first simulation verification against NIST-FIPS-180-4 test vectors "abc" passed.
|
68 |
|
|
-- 2016/06/07 v0.01.0105 [JD] verification against all NIST-FIPS-180-4 test vectors passed.
|
69 |
|
|
-- 2016/06/11 v0.01.0105 [JD] verification against NIST-SHA2_Additional test vectors #1 to #10 passed.
|
70 |
|
|
-- 2016/06/11 v0.01.0110 [JD] optimized controller states, reduced 2 clocks per block, added lookahead register feedback.
|
71 |
9 |
jdoin |
-- 2016/09/25 v0.01.0220 [JD] changed 'di_ack_i' name to 'di_wr_i', and changed semantics to 'data write'.
|
72 |
2 |
jdoin |
--
|
73 |
|
|
--
|
74 |
|
|
-----------------------------------------------------------------------------------------------------------------------
|
75 |
|
|
library ieee;
|
76 |
|
|
use ieee.std_logic_1164.all;
|
77 |
|
|
use ieee.numeric_std.all;
|
78 |
|
|
|
79 |
|
|
|
80 |
|
|
entity gv_sha256 is
|
81 |
|
|
port (
|
82 |
|
|
-- clock and core enable
|
83 |
|
|
clk_i : in std_logic := 'U'; -- system clock
|
84 |
|
|
ce_i : in std_logic := 'U'; -- core clock enable
|
85 |
|
|
-- input data
|
86 |
|
|
di_i : in std_logic_vector (31 downto 0) := (others => 'U'); -- big endian input message words
|
87 |
|
|
bytes_i : in std_logic_vector (1 downto 0) := (others => 'U'); -- valid bytes in input word
|
88 |
|
|
-- start/end commands
|
89 |
|
|
start_i : in std_logic := 'U'; -- reset the engine and start a new hash
|
90 |
|
|
end_i : in std_logic := 'U'; -- marks end of last block data input
|
91 |
|
|
-- handshake
|
92 |
|
|
di_req_o : out std_logic; -- requests data input for next word
|
93 |
9 |
jdoin |
di_wr_i : in std_logic := 'U'; -- high for di_i valid, low for hold
|
94 |
2 |
jdoin |
error_o : out std_logic; -- signalizes error. output data is invalid
|
95 |
|
|
do_valid_o : out std_logic; -- when high, the output is valid
|
96 |
|
|
-- 256bit output registers
|
97 |
|
|
H0_o : out std_logic_vector (31 downto 0);
|
98 |
|
|
H1_o : out std_logic_vector (31 downto 0);
|
99 |
|
|
H2_o : out std_logic_vector (31 downto 0);
|
100 |
|
|
H3_o : out std_logic_vector (31 downto 0);
|
101 |
|
|
H4_o : out std_logic_vector (31 downto 0);
|
102 |
|
|
H5_o : out std_logic_vector (31 downto 0);
|
103 |
|
|
H6_o : out std_logic_vector (31 downto 0);
|
104 |
|
|
H7_o : out std_logic_vector (31 downto 0)
|
105 |
|
|
);
|
106 |
|
|
end gv_sha256;
|
107 |
|
|
|
108 |
|
|
architecture rtl of gv_sha256 is
|
109 |
|
|
-- internal register data values
|
110 |
|
|
signal R0_data : std_logic_vector (31 downto 0);
|
111 |
|
|
signal R1_data : std_logic_vector (31 downto 0);
|
112 |
|
|
signal R2_data : std_logic_vector (31 downto 0);
|
113 |
|
|
signal R3_data : std_logic_vector (31 downto 0);
|
114 |
|
|
signal R4_data : std_logic_vector (31 downto 0);
|
115 |
|
|
signal R5_data : std_logic_vector (31 downto 0);
|
116 |
|
|
signal R6_data : std_logic_vector (31 downto 0);
|
117 |
|
|
signal R7_data : std_logic_vector (31 downto 0);
|
118 |
|
|
-- initial hash data values
|
119 |
|
|
signal K0_data : std_logic_vector (31 downto 0);
|
120 |
|
|
signal K1_data : std_logic_vector (31 downto 0);
|
121 |
|
|
signal K2_data : std_logic_vector (31 downto 0);
|
122 |
|
|
signal K3_data : std_logic_vector (31 downto 0);
|
123 |
|
|
signal K4_data : std_logic_vector (31 downto 0);
|
124 |
|
|
signal K5_data : std_logic_vector (31 downto 0);
|
125 |
|
|
signal K6_data : std_logic_vector (31 downto 0);
|
126 |
|
|
signal K7_data : std_logic_vector (31 downto 0);
|
127 |
|
|
-- hash result lookahead port
|
128 |
|
|
signal N0_data : std_logic_vector (31 downto 0);
|
129 |
|
|
signal N1_data : std_logic_vector (31 downto 0);
|
130 |
|
|
signal N2_data : std_logic_vector (31 downto 0);
|
131 |
|
|
signal N3_data : std_logic_vector (31 downto 0);
|
132 |
|
|
signal N4_data : std_logic_vector (31 downto 0);
|
133 |
|
|
signal N5_data : std_logic_vector (31 downto 0);
|
134 |
|
|
signal N6_data : std_logic_vector (31 downto 0);
|
135 |
|
|
signal N7_data : std_logic_vector (31 downto 0);
|
136 |
|
|
-- hash result data
|
137 |
|
|
signal H0_data : std_logic_vector (31 downto 0);
|
138 |
|
|
signal H1_data : std_logic_vector (31 downto 0);
|
139 |
|
|
signal H2_data : std_logic_vector (31 downto 0);
|
140 |
|
|
signal H3_data : std_logic_vector (31 downto 0);
|
141 |
|
|
signal H4_data : std_logic_vector (31 downto 0);
|
142 |
|
|
signal H5_data : std_logic_vector (31 downto 0);
|
143 |
|
|
signal H6_data : std_logic_vector (31 downto 0);
|
144 |
|
|
signal H7_data : std_logic_vector (31 downto 0);
|
145 |
|
|
-- message schedule word datapath
|
146 |
|
|
signal Mi_data : std_logic_vector (31 downto 0);
|
147 |
|
|
signal Wt_data : std_logic_vector (31 downto 0);
|
148 |
|
|
-- coefficients ROMs
|
149 |
|
|
signal Kt_data : std_logic_vector (31 downto 0);
|
150 |
|
|
signal Kt_addr : std_logic_vector (5 downto 0);
|
151 |
|
|
-- padding control
|
152 |
|
|
signal words_sel : std_logic_vector (1 downto 0);
|
153 |
|
|
signal bytes_ena : std_logic_vector (3 downto 0);
|
154 |
|
|
signal one_insert : std_logic;
|
155 |
|
|
signal msg_bitlen : std_logic_vector (63 downto 0);
|
156 |
|
|
signal pad_data : std_logic_vector (31 downto 0);
|
157 |
|
|
-- block mux selectors
|
158 |
|
|
signal sch_ld : std_logic;
|
159 |
|
|
signal core_ld : std_logic;
|
160 |
|
|
signal oregs_ld : std_logic;
|
161 |
|
|
-- block clock enables
|
162 |
|
|
signal sch_ce : std_logic;
|
163 |
|
|
signal core_ce : std_logic;
|
164 |
|
|
signal oregs_ce : std_logic;
|
165 |
|
|
-- output data valid / error
|
166 |
|
|
signal data_valid : std_logic;
|
167 |
|
|
signal error_pad : std_logic;
|
168 |
|
|
signal error_ctrl : std_logic;
|
169 |
|
|
begin
|
170 |
|
|
--=============================================================================================
|
171 |
|
|
-- INTERNAL COMPONENT INSTANTIATIONS AND CONNECTIONS
|
172 |
|
|
--=============================================================================================
|
173 |
|
|
|
174 |
|
|
-- control path core logic
|
175 |
|
|
Inst_sha256_control: entity work.sha256_control(rtl)
|
176 |
|
|
port map(
|
177 |
|
|
-- inputs
|
178 |
|
|
clk_i => clk_i,
|
179 |
|
|
ce_i => ce_i,
|
180 |
|
|
bytes_i => bytes_i,
|
181 |
9 |
jdoin |
wr_i => di_wr_i,
|
182 |
2 |
jdoin |
start_i => start_i,
|
183 |
|
|
end_i => end_i,
|
184 |
|
|
error_i => error_pad,
|
185 |
|
|
-- output control signals
|
186 |
|
|
bitlen_o => msg_bitlen,
|
187 |
|
|
words_sel_o => words_sel,
|
188 |
|
|
Kt_addr_o => Kt_addr,
|
189 |
|
|
sch_ld_o => sch_ld,
|
190 |
|
|
core_ld_o => core_ld,
|
191 |
|
|
oregs_ld_o => oregs_ld,
|
192 |
|
|
sch_ce_o => sch_ce,
|
193 |
|
|
core_ce_o => core_ce,
|
194 |
|
|
oregs_ce_o => oregs_ce,
|
195 |
|
|
one_insert_o => one_insert,
|
196 |
|
|
bytes_ena_o => bytes_ena,
|
197 |
|
|
di_req_o => di_req_o,
|
198 |
|
|
data_valid_o => data_valid,
|
199 |
|
|
error_o => error_ctrl
|
200 |
|
|
);
|
201 |
|
|
|
202 |
|
|
-- datapath: sha256 byte padding
|
203 |
|
|
Inst_sha256_padding: entity work.sha256_padding(rtl)
|
204 |
|
|
port map(
|
205 |
|
|
words_sel_i => words_sel,
|
206 |
|
|
one_insert_i => one_insert,
|
207 |
|
|
bytes_ena_i => bytes_ena,
|
208 |
|
|
bitlen_i => msg_bitlen,
|
209 |
|
|
di_i => di_i,
|
210 |
|
|
do_o => Mi_data,
|
211 |
|
|
error_o => error_pad
|
212 |
|
|
);
|
213 |
|
|
|
214 |
|
|
-- datapath: sha256 message schedule
|
215 |
|
|
Inst_sha256_msg_sch: entity work.sha256_msg_sch(rtl)
|
216 |
|
|
port map(
|
217 |
|
|
clk_i => clk_i,
|
218 |
|
|
ce_i => sch_ce,
|
219 |
|
|
ld_i => sch_ld,
|
220 |
|
|
M_i => Mi_data,
|
221 |
|
|
Wt_o => Wt_data
|
222 |
|
|
);
|
223 |
|
|
|
224 |
|
|
-- datapath: sha256 core logic
|
225 |
|
|
Inst_sha256_hash_core: entity work.sha256_hash_core(rtl)
|
226 |
|
|
port map(
|
227 |
|
|
clk_i => clk_i,
|
228 |
|
|
ce_i => core_ce,
|
229 |
|
|
ld_i => core_ld,
|
230 |
|
|
-- initial hash data values
|
231 |
|
|
A_i => N0_data,
|
232 |
|
|
B_i => N1_data,
|
233 |
|
|
C_i => N2_data,
|
234 |
|
|
D_i => N3_data,
|
235 |
|
|
E_i => N4_data,
|
236 |
|
|
F_i => N5_data,
|
237 |
|
|
G_i => N6_data,
|
238 |
|
|
H_i => N7_data,
|
239 |
|
|
-- block hash values
|
240 |
|
|
A_o => R0_data,
|
241 |
|
|
B_o => R1_data,
|
242 |
|
|
C_o => R2_data,
|
243 |
|
|
D_o => R3_data,
|
244 |
|
|
E_o => R4_data,
|
245 |
|
|
F_o => R5_data,
|
246 |
|
|
G_o => R6_data,
|
247 |
|
|
H_o => R7_data,
|
248 |
|
|
-- key coefficients
|
249 |
|
|
Kt_i => Kt_data,
|
250 |
|
|
-- message schedule word input
|
251 |
|
|
Wt_i => Wt_data
|
252 |
|
|
);
|
253 |
|
|
|
254 |
|
|
-- datapath: sha256 output registers
|
255 |
|
|
Inst_sha256_regs: entity work.sha256_regs(rtl)
|
256 |
|
|
port map(
|
257 |
|
|
clk_i => clk_i,
|
258 |
|
|
ce_i => oregs_ce,
|
259 |
|
|
ld_i => oregs_ld,
|
260 |
|
|
-- register data from the core logic
|
261 |
|
|
A_i => R0_data,
|
262 |
|
|
B_i => R1_data,
|
263 |
|
|
C_i => R2_data,
|
264 |
|
|
D_i => R3_data,
|
265 |
|
|
E_i => R4_data,
|
266 |
|
|
F_i => R5_data,
|
267 |
|
|
G_i => R6_data,
|
268 |
|
|
H_i => R7_data,
|
269 |
|
|
-- initial hash values
|
270 |
|
|
K0_i => K0_data,
|
271 |
|
|
K1_i => K1_data,
|
272 |
|
|
K2_i => K2_data,
|
273 |
|
|
K3_i => K3_data,
|
274 |
|
|
K4_i => K4_data,
|
275 |
|
|
K5_i => K5_data,
|
276 |
|
|
K6_i => K6_data,
|
277 |
|
|
K7_i => K7_data,
|
278 |
|
|
-- lookahead output hash values, one pipeline advanced
|
279 |
|
|
N0_o => N0_data,
|
280 |
|
|
N1_o => N1_data,
|
281 |
|
|
N2_o => N2_data,
|
282 |
|
|
N3_o => N3_data,
|
283 |
|
|
N4_o => N4_data,
|
284 |
|
|
N5_o => N5_data,
|
285 |
|
|
N6_o => N6_data,
|
286 |
|
|
N7_o => N7_data,
|
287 |
|
|
-- output hash values
|
288 |
|
|
H0_o => H0_data,
|
289 |
|
|
H1_o => H1_data,
|
290 |
|
|
H2_o => H2_data,
|
291 |
|
|
H3_o => H3_data,
|
292 |
|
|
H4_o => H4_data,
|
293 |
|
|
H5_o => H5_data,
|
294 |
|
|
H6_o => H6_data,
|
295 |
|
|
H7_o => H7_data
|
296 |
|
|
);
|
297 |
|
|
|
298 |
|
|
-- coefficients ROM: modelled as an asynchronously addressable ROM
|
299 |
|
|
Inst_sha256_kt_rom: entity work.sha256_kt_rom(behavioral)
|
300 |
|
|
port map(
|
301 |
|
|
addr_i => Kt_addr,
|
302 |
|
|
dout_o => Kt_data
|
303 |
|
|
);
|
304 |
|
|
|
305 |
|
|
-- init output data ROM: modelled as a statically defined constant
|
306 |
|
|
Inst_sha256_ki_rom: entity work.sha256_ki_rom(behavioral)
|
307 |
|
|
port map(
|
308 |
|
|
K0_o => K0_data,
|
309 |
|
|
K1_o => K1_data,
|
310 |
|
|
K2_o => K2_data,
|
311 |
|
|
K3_o => K3_data,
|
312 |
|
|
K4_o => K4_data,
|
313 |
|
|
K5_o => K5_data,
|
314 |
|
|
K6_o => K6_data,
|
315 |
|
|
K7_o => K7_data
|
316 |
|
|
);
|
317 |
|
|
|
318 |
|
|
--=============================================================================================
|
319 |
|
|
-- OUTPUTS LOGIC
|
320 |
|
|
--=============================================================================================
|
321 |
|
|
|
322 |
|
|
error_o_proc: error_o <= error_ctrl;
|
323 |
|
|
do_valid_o_proc: do_valid_o <= data_valid;
|
324 |
|
|
H0_o_proc: H0_o <= H0_data;
|
325 |
|
|
H1_o_proc: H1_o <= H1_data;
|
326 |
|
|
H2_o_proc: H2_o <= H2_data;
|
327 |
|
|
H3_o_proc: H3_o <= H3_data;
|
328 |
|
|
H4_o_proc: H4_o <= H4_data;
|
329 |
|
|
H5_o_proc: H5_o <= H5_data;
|
330 |
|
|
H6_o_proc: H6_o <= H6_data;
|
331 |
|
|
H7_o_proc: H7_o <= H7_data;
|
332 |
|
|
|
333 |
|
|
end rtl;
|
334 |
|
|
|