Commit 1aaf7d0ed1459f50f2908650330bc3d966132765

Authored by Brice Colombier
1 parent 6a27f428b8
Exists in master

CASCADE working

Showing 27 changed files with 1380 additions and 1747 deletions

CASCADE/cascade.py View file @ 1aaf7d0
... ... @@ -82,26 +82,25 @@
82 82 even_parity_blocks.extend(indices)
83 83 indices = fl.flatten(indices)
84 84 reference_response = fl.flatten(reference_response)
85   - print "Indices to flip", indices_to_flip
86 85 if blocks_to_correct:
87 86 # Error correction step
88 87 fb.flip_bits(reference_response, indices_to_flip, indices)
89 88 indices_to_flip = []
90 89 blocks_to_correct = []
91   - # if passe > 0:
92   - # # Backtracking process
93   - # while odd_parity_blocks:
94   - # backtracked_pos = 0
95   - # block_to_correct = min(odd_parity_blocks, key=len) # Get the smallest block
96   - # reference_response_block = [reference_response[indices.index(x)] for x in block_to_correct]
97   - # while len(block_to_correct) > 2:
98   - # [reference_response_block], [block_to_correct] = bi_par.binary_par([reference_response_block], [block_to_correct], tclsh, board_manager)
99   - # # Final BINARY execution where single PUF bits are queried from the board
100   - # _, backtracked_pos = bi_par.binary_par([reference_response_block], [block_to_correct], tclsh, board_manager)
101   - # # backtracked_pos = bi.binary(reference_response_block, block_to_correct, response_on_board)
102   - # fb.flip_bits(reference_response, backtracked_pos, indices)
103   - # # Move blocks from one group to the other if they contain the bit to flip
104   - # sb.swap_blocks(even_parity_blocks, odd_parity_blocks, backtracked_pos[0])
  90 + if passe > 0:
  91 + # Backtracking process
  92 + while odd_parity_blocks:
  93 + backtracked_pos = 0
  94 + block_to_correct = min(odd_parity_blocks, key=len) # Get the smallest block
  95 + reference_response_block = [reference_response[indices.index(x)] for x in block_to_correct]
  96 + while len(block_to_correct) > 2:
  97 + [reference_response_block], [block_to_correct] = bi_par.binary_par([reference_response_block], [block_to_correct], tclsh, board_manager, len(reference_response)*4)
  98 + # Final BINARY execution where single PUF bits are queried from the board
  99 + _, backtracked_pos = bi_par.binary_par([reference_response_block], [block_to_correct], tclsh, board_manager, len(reference_response)*4)
  100 + # backtracked_pos = bi.binary(reference_response_block, block_to_correct, response_on_board)
  101 + fb.flip_bits(reference_response, backtracked_pos, indices)
  102 + # Move blocks from one group to the other if they contain the bit to flip
  103 + sb.swap_blocks(even_parity_blocks, odd_parity_blocks, backtracked_pos[0])
105 104 if [x for x in even_parity_blocks if x in odd_parity_blocks]:
106 105 raise ValueError("Blocks are simultaneously in the even and odd group")
107 106 # Un-shuffle
CASCADE/get_parities_from_indices.py View file @ 1aaf7d0
... ... @@ -26,7 +26,7 @@
26 26  
27 27 command = board_manager.command_get_parities_from_indices(indices, response_length)
28 28 parities = tclsh.eval(command)
29   - parities = [int(i) for i in list(parities.replace(" ", ""))]
  29 + parities = [int(i) for i in bin(int(parities, 16))[2:].zfill(len(indices))]
30 30 return parities
31 31  
32 32  
HECTOR_data_acq.tcl View file @ 1aaf7d0
... ... @@ -68,7 +68,7 @@
68 68 }
69 69  
70 70 # Poll the serial device for input data
71   -proc pollDevice {device {verbose 0}} {
  71 +proc pollDevice {device {verbose 0} } {
72 72  
73 73 # Read the input serial buffer
74 74 set data [read [lindex $device 1]]
... ... @@ -106,6 +106,18 @@
106 106 set ret(fpga_status) [binToHEX $fpga_status]
107 107 return [list $ret(fpga_status) $ret(fpga_data)]
108 108 }
  109 +
  110 +# Get the puf response packet header offset
  111 + set offset [string first "\x13\xC5\x00\x00" $data]
  112 + if {$offset != -1} {
  113 +# Get the status fields
  114 + set fpga_status [string range $data [expr $offset + 4] [expr $offset + 7]]
  115 + set fpga_data [string range $data [expr $offset + 8] end]
  116 +
  117 + set ret(fpga_data) [binToHEX $fpga_data]
  118 + set ret(fpga_status) [binToHEX $fpga_status]
  119 + return [list $ret(fpga_status) $ret(fpga_data)]
  120 + }
109 121 }
110 122 } else {
111 123 set ret(response) -1
... ... @@ -311,6 +323,41 @@
311 323 return $resp
312 324 }
313 325  
  326 +proc sendPufData {device puf_mode mb2db_nmb db2mb_nmb data {verbose 0}} {
  327 + global UART_timeout
  328 + global uart_check_timeout
  329 +
  330 + # generate first word which consists of chip select and readwrite bit
  331 +
  332 + set data_out "\x13\xC9\x00\x00\x00[binary format c1 $puf_mode][binary format c1 $mb2db_nmb][binary format c1 $db2mb_nmb]"
  333 +
  334 + for {set i 0} {$i < $mb2db_nmb} {incr i} {
  335 + append data_out [binary format W1 [lindex $data $i]]
  336 + }
  337 +
  338 + if {$verbose != 0} {
  339 + puts "Sending: [binToHEX $data_out]"
  340 + }
  341 +
  342 + puts -nonewline [lindex $device 1] $data_out
  343 +
  344 +# Return the response of the command
  345 + set resp "-1 1"
  346 + set start [clock seconds]
  347 + while { [string match $resp "-1 1"] } {
  348 + set resp [pollDevice $device $verbose]
  349 + if { [clock seconds] > [expr $start + $UART_timeout] } {
  350 + break
  351 + }
  352 + wait_ms $uart_check_timeout
  353 + }
  354 +
  355 +
  356 + return $resp
  357 +}
  358 +
  359 +
  360 +
314 361 proc sendFabricReset {device {verbose 0}} {
315 362 global UART_timeout
316 363 global uart_check_timeout
... ... @@ -752,75 +799,5 @@
752 799 puts "Acquired data are available in the file $filename"
753 800  
754 801 return 0
755   -}
756   -
757   -proc hex2bin {hexIn {spaceSeparated 0}} {
758   - set outStr ""
759   -
760   - for {set i 0} {$i < [string length $hexIn]} {incr i} {
761   - set char [string index $hexIn $i]
762   - switch -glob $char {
763   - "0" {set outStr "$outStr 0000"}
764   - "1" {set outStr "$outStr 0001"}
765   - "2" {set outStr "$outStr 0010"}
766   - "3" {set outStr "$outStr 0011"}
767   - "4" {set outStr "$outStr 0100"}
768   - "5" {set outStr "$outStr 0101"}
769   - "6" {set outStr "$outStr 0110"}
770   - "7" {set outStr "$outStr 0111"}
771   - "8" {set outStr "$outStr 1000"}
772   - "9" {set outStr "$outStr 1001"}
773   - "A" {set outStr "$outStr 1010"}
774   - "a" {set outStr "$outStr 1010"}
775   - "B" {set outStr "$outStr 1011"}
776   - "b" {set outStr "$outStr 1011"}
777   - "C" {set outStr "$outStr 1100"}
778   - "c" {set outStr "$outStr 1100"}
779   - "D" {set outStr "$outStr 1101"}
780   - "d" {set outStr "$outStr 1101"}
781   - "E" {set outStr "$outStr 1110"}
782   - "e" {set outStr "$outStr 1110"}
783   - "F" {set outStr "$outStr 1111"}
784   - "f" {set outStr "$outStr 1111"}
785   - default {}
786   - }
787   - }
788   -
789   - if { $spaceSeparated == 0 } {
790   - set outStr [string map {" " {}} $outStr]
791   - }
792   -
793   - return $outStr
794   -}
795   -
796   -proc bin2hex {binIn} {
797   - set outStr ""
798   -
799   - for {set i 0} {$i < [string length $binIn]} {set i [expr $i+4]} {
800   - set char4 [string range $binIn [expr $i] [expr $i+3] ]
801   - switch -glob $char4 {
802   - "0000" {set outStr "$outStr 0"}
803   - "0001" {set outStr "$outStr 1"}
804   - "0010" {set outStr "$outStr 2"}
805   - "0011" {set outStr "$outStr 3"}
806   - "0100" {set outStr "$outStr 4"}
807   - "0101" {set outStr "$outStr 5"}
808   - "0110" {set outStr "$outStr 6"}
809   - "0111" {set outStr "$outStr 7"}
810   - "1000" {set outStr "$outStr 8"}
811   - "1001" {set outStr "$outStr 9"}
812   - "1010" {set outStr "$outStr A"}
813   - "1011" {set outStr "$outStr B"}
814   - "1100" {set outStr "$outStr C"}
815   - "1101" {set outStr "$outStr D"}
816   - "1110" {set outStr "$outStr E"}
817   - "1111" {set outStr "$outStr F"}
818   - default {}
819   - }
820   - }
821   -
822   - set outStr [string map {" " {}} $outStr]
823   -
824   - return $outStr
825 802 }
  1 +def otp(plaintext, key):
  2 + if len(plaintext) != len(key):
  3 + raise ValueError("The key and the plaintext should have the same length")
  4 + elif set(plaintext+"01") > set(['0', '1']):
  5 + raise ValueError("The plaintext contains illegal characters")
  6 + elif set(key+"01") > set(['0', '1']):
  7 + raise ValueError("The key contains illegal characters")
  8 + else:
  9 + ciphertext = ""
  10 + for plaintext_bit, key_bit in zip(plaintext, key):
  11 + ciphertext+=str(int(plaintext_bit)^int(key_bit))
  12 + return ciphertext
  13 +
  14 +if __name__ == "__main__":
  15 + print otp("0000000000000000", "0000000001111111")
  16 +
... ... @@ -9,8 +9,6 @@
9 9 # Date: 2016-10-13
10 10  
11 11 import random
12   -import sys
13   -import time
14 12  
15 13 import tkFileDialog
16 14 from Tkinter import *
... ... @@ -180,7 +178,7 @@
180 178 def open_server_reference_response(self):
181 179 self.update_status("")
182 180 rrtypes = [("Reference response file", ".txt")]
183   - self.server_reference_response_file.set(tkFileDialog.askopenfilename(initialdir = "./../User_space/",
  181 + self.server_reference_response_file.set(tkFileDialog.askopenfilename(initialdir = "./user_space/",
184 182 filetypes=rrtypes))
185 183 with open(self.server_reference_response_file.get(), "r") as rrfile:
186 184 line = rrfile.readline()
... ... @@ -189,7 +187,7 @@
189 187 else:
190 188 self.server_reference_response = str(line[20:])
191 189 self.server_reference_response_displayed.set(self.server_reference_response)
192   - self.server_reference_response = response_converter_to_bin_list(self.server_reference_response)
  190 + self.server_reference_response = response_converter_to_bin_list(self.server_reference_response)[::-1]
193 191 self.update_status("")
194 192 if self.connected.get() == True:
195 193 self.setState(self.CASCADE_frame, state = "normal")
196 194  
... ... @@ -231,16 +229,16 @@
231 229  
232 230 def get_PUF_response(self):
233 231 self.update_status("")
234   - self.PUF_response_displayed.set("")
235   - try:
236   - self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
237   - self.tcl_obj.eval(self.board_manager.generate_response())
238   - temp_hex_response = self.tcl_obj.eval(self.board_manager.offload_response())
239   - self.PUF_response = list(reversed(response_converter_to_bin_list(temp_hex_response)))
240   - self.PUF_response_displayed.set(response_converter_to_hex(self.PUF_response))
241   - except:
  232 + # self.PUF_response_displayed.set("")
  233 + self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
  234 + status, temp_hex_response = self.tcl_obj.eval(self.board_manager.generate_response()).split(" ")
  235 + if status != "CAFEBABE":
242 236 self.server_reference_response_displayed.set("")
243 237 self.update_status("Response could not be obtained")
  238 + self.PUF_response_displayed.set("")
  239 + else:
  240 + self.PUF_response = list(reversed(response_converter_to_bin_list(temp_hex_response)))
  241 + self.PUF_response_displayed.set(response_converter_to_hex(self.PUF_response))
244 242  
245 243 def save_as_reference_response(self):
246 244 self.update_status("")
... ... @@ -298,8 +296,8 @@
298 296 self.update_status("Could not connect to the board")
299 297 self.connected.set(False)
300 298 else: # Connection successful
301   - self.com_port_button_connect.configure(state=DISABLED)
302   - self.com_port_button_disconnect.configure(state=NORMAL)
  299 + self.com_port_button_connect.configure(state="disabled")
  300 + self.com_port_button_disconnect.configure(state="normal")
303 301 self.connected.set(True)
304 302 self.board_status.set("Board Connected")
305 303 self.board_status_label.configure(foreground="darkgreen")
306 304  
... ... @@ -310,11 +308,16 @@
310 308 self.update_status("")
311 309 try:
312 310 self.tcl_obj.eval(self.board_manager.disconnect())
313   - self.com_port_button_disconnect.configure(state=DISABLED)
314   - self.com_port_button_connect.configure(state=NORMAL)
  311 + self.com_port_button_disconnect.configure(state="disabled")
  312 + self.com_port_button_connect.configure(state="normal")
315 313 self.connected.set(False)
316 314 self.board_status.set("Board not connected")
317 315 self.board_status_label.configure(foreground="red")
  316 + self.setState(self.CASCADE_frame, state = "disabled")
  317 + self.setState(self.key_derivation_frame, state = "disabled")
  318 + self.setState(self.activation_word_encryption_frame, state = "disabled")
  319 + self.setState(self.activation_process_frame, state = "disabled")
  320 + self.setState(self.get_PUF_response_frame, state = "disabled")
318 321 except:
319 322 pass
320 323  
... ... @@ -471,10 +474,6 @@
471 474 self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
472 475 self.tcl_obj.eval(self.board_manager.generate_response())
473 476 server_before = self.server_reference_response
474   - print "Server:", str.upper(hex(int(str(self.server_reference_response)[1:-1].replace(", ", ""), 2))[2:-1])
475   - on_board = response_converter_to_bin_list(self.tcl_obj.eval(self.board_manager.offload_response()))
476   - print "DBoard:", str.upper(hex(int(str(list(reversed(on_board)))[1:-1].replace(", ", ""), 2))[2:-1])
477   - print "Differences before/on_board: ", [a for (a, (b, c)) in enumerate(zip(server_before, list(reversed(on_board)))) if b != c]
478 477 self.server_reference_response = cascade(self.server_reference_response,
479 478 0.02,
480 479 int(self.reconciliation_parameter_number_of_passes_spinbox.get()),
... ... @@ -482,9 +481,9 @@
482 481 self.board_manager,
483 482 int(self.reconciliation_parameter_initial_block_size_spinbox.get()))
484 483 server_after = self.server_reference_response
485   - on_board = response_converter_to_bin_list(self.tcl_obj.eval(self.board_manager.offload_response()))
486   - print "Differences after/on_board: ", [a for (a, (b, c)) in enumerate(zip(server_after, list(reversed(on_board)))) if b != c]
487   - print "Differences before/after: ", [a for (a, (b, c)) in enumerate(zip(server_before, server_after)) if b != c]
  484 + print "Befor :", server_before
  485 + print "After :", server_after
  486 + print "Diffs :", [a for (a, (b, c)) in enumerate(zip(server_before, server_after)) if b != c]
488 487 print ("Reconciliation done")
489 488  
490 489 def update_status(self, text):
basic_infrastructure/hdl/TEROPUF_core.vhd View file @ 1aaf7d0
1   --- **********************************************************************************************
2   --- ** Copyright (c) Laboratoire Hubert Curien, All rights reserved. **
3   --- ** **
4   --- ** **
5   --- ** The data exchange is covered by the HECTOR project NDA. **
6   --- ** The data provided by us are for use within the HECTOR project only and are sole IP **
7   --- ** of Laboratoire Hubert Curien. Any other use or distribution **
8   --- ** thereof has to be granted by us and otherwise will be in violation of the project non **
9   --- ** disclosure agreement. **
10   --- ** **
11   --- **********************************************************************************************
12   ----------------------------------------------------------------------
13   ---
14   --- Design unit: TERO PUF core
15   ---
16   --- File name: TEROPUF_core.vhd
17   ---
18   --- Description: Core of the TERO composed of demux, tero cells, mux and comparator.
19   ---
20   --- Autor: Ugo Mureddu, Nathalie Bochard, Hubert Curien Laboratory, France
21   ---
22   --- Copyright: Hubert Curien Laboratory
23   ---
24   --- Revision: Version 1.00, June 2016
25   ---
26   ----------------------------------------------------------------------
27   -
28   -
29   -LIBRARY ieee;
30   -USE ieee.std_logic_1164.ALL;
31   -USE IEEE.NUMERIC_STD.ALL;
32   -
33   -LIBRARY WORK;
34   -USE WORK.lab_hc_pkg.ALL;
35   -
36   -LIBRARY smartfusion2;
37   -USE smartfusion2.ALL;
38   -
39   -ENTITY TEROPUF_core IS
40   - PORT
41   - (
42   - clk : IN STD_LOGIC; --global clk
43   - rst : IN STD_LOGIC := '1'; --reset counters
44   - ena : IN STD_LOGIC; --activate tero cells
45   - selec_in : IN STD_LOGIC_VECTOR(SEL_WIDTH-1 DOWNTO 0) := (OTHERS => '0'); --select tero cell
46   - output_puf : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); --comparison result
47   - strobe : OUT STD_LOGIC --data ready signal
48   - );
49   -END TEROPUF_core;
50   -
51   -ARCHITECTURE rtl OF TEROPUF_core IS
52   -
53   ------------------------
54   --- Tero cell component --
55   ------------------------
56   - COMPONENT TERO_core IS
57   - GENERIC (
58   - length : INTEGER := NDE1_VAL
59   - );
60   - PORT(
61   - ctrl : IN STD_LOGIC; -- Desables oscillator output
62   - tero_out : OUT STD_LOGIC -- Oscillator output
63   - );
64   - END COMPONENT;
65   -
66   -
67   ---------------------
68   --- CLKBUF --
69   ---------------------
70   - COMPONENT CLKINT
71   - -- PORT LIST
72   - PORT(
73   - -- INPUTS
74   - A : IN STD_LOGIC;
75   - -- OUTPUTS
76   - Y : OUT STD_LOGIC
77   - );
78   - END COMPONENT;
79   -
80   ---------------------------
81   --- multiplexor 128 to 1 --
82   ---------------------------
83   - COMPONENT mux_tero IS
84   -
85   - GENERIC (
86   - WIDTH : INTEGER := WIDTH_MUX;
87   - SELECT_WIDTH : INTEGER := SEL_WIDTH);
88   -
89   - PORT (
90   - data_in : IN STD_LOGIC_VECTOR((WIDTH-1) DOWNTO 0);
91   - selection : IN STD_LOGIC_VECTOR((SELECT_WIDTH-1) DOWNTO 0);
92   - data_out : OUT STD_LOGIC
93   - );
94   -
95   - END COMPONENT;
96   -
97   -----------------------------
98   --- demultiplexor 1 to 128 --
99   -----------------------------
100   - COMPONENT demux IS
101   -
102   - GENERIC (
103   - WIDTH : INTEGER := WIDTH_MUX;
104   - SELECT_WIDTH : INTEGER := SEL_WIDTH);
105   -
106   - PORT (
107   - data_in : IN STD_LOGIC;
108   - selection : IN STD_LOGIC_VECTOR((SELECT_WIDTH-1) DOWNTO 0);
109   - data_out : OUT STD_LOGIC_VECTOR((WIDTH-1) DOWNTO 0));
110   -
111   - END COMPONENT;
112   -
113   -----------------------
114   --- Internal signals --
115   -----------------------
116   -
117   - SIGNAL cnt1 : UNSIGNED(9 DOWNTO 0); -- signal for storing number of rising edges of the first TERO
118   - SIGNAL cnt2 : UNSIGNED(9 DOWNTO 0); -- signal for storing number of rising edges of the second TERO
119   - SIGNAL cnt1_done_int : STD_LOGIC; -- signal indicating that the first counter has reached the value of 1024 rising edges (randomly choosen value!)
120   - SIGNAL cnt2_done_int : STD_LOGIC; -- signal indicating that the second counter has reached the value of 1024 rising edges (randomly choosen value!)
121   - SIGNAL cnt_ctrl : UNSIGNED (7 DOWNTO 0) := (OTHERS => '0'); --signal activating ctrl for a defined period
122   - SIGNAL ctrl : STD_LOGIC; -- activate the TERO cells
123   - SIGNAL mux1_out : STD_LOGIC; -- TERO cell output muxed
124   - SIGNAL mux2_out : STD_LOGIC; -- TERO cell output muxed
125   - SIGNAL mux1_out_buff : STD_LOGIC; -- TERO cell output muxed and buffered
126   - SIGNAL mux2_out_buff : STD_LOGIC; -- TERO cell output muxed and buffered
127   - SIGNAL tero_out_1 : STD_LOGIC_VECTOR((NRO_VAL - 1) DOWNTO 0); --TERO cell output
128   - SIGNAL teros_ctrl : STD_LOGIC_VECTOR((NRO_VAL - 1) DOWNTO 0) := (OTHERS => '0'); -- Desables oscillator output
129   - SIGNAL tero_out_2 : STD_LOGIC_VECTOR((NRO_VAL - 1) DOWNTO 0); --TERO cell output
130   - SIGNAL sub_result : UNSIGNED(9 DOWNTO 0); -- difference between the two counter values
131   -------------------------------
132   --- BEGIN ARCHITECTURE --
133   -------------------------------
134   -BEGIN
135   -
136   -------------------------------
137   --- Ring oscillator array --
138   -------------------------------
139   - tero_array_1 :
140   - FOR i IN 1 TO NRO_VAL GENERATE
141   - BEGIN
142   - ring_n : TERO_core
143   - PORT MAP(
144   - ctrl => teros_ctrl(i-1), -- Desables oscillator output
145   - tero_out => tero_out_1(i-1));
146   - END GENERATE tero_array_1;
147   -
148   - tero_array_2 :
149   - FOR i IN 1 TO NRO_VAL GENERATE
150   - BEGIN
151   - ring_n : TERO_core
152   - PORT MAP(
153   - ctrl => teros_ctrl(i-1), -- Desables oscillator output
154   - tero_out => tero_out_2(i-1));
155   - END GENERATE tero_array_2;
156   -
157   -----------------------------------------------------
158   --- Switching TERO outputs using multiplexers --
159   -----------------------------------------------------
160   -
161   - mux_out1_gen : mux_tero
162   - PORT MAP(
163   - data_in => tero_out_1,
164   - selection => selec_in,
165   - data_out => mux1_out);
166   -
167   -
168   - mux_out2_gen : mux_tero
169   - PORT MAP(
170   - data_in => tero_out_2,
171   - selection => selec_in,
172   - data_out => mux2_out);
173   -
174   - ena_gen : demux
175   - PORT MAP(
176   - data_in => ctrl,
177   - selection => selec_in,
178   - data_out => teros_ctrl
179   - );
180   -
181   -------------------------------
182   --- MUX1_OUT_BUFF
183   -------------------------------
184   - CLKBUF1 : CLKINT
185   - PORT MAP(
186   - -- Inputs
187   - A => mux1_out,
188   - -- Outputs
189   - Y => mux1_out_buff
190   - );
191   -
192   - ------------------------------
193   --- MUX2_OUT_BUFF
194   -------------------------------
195   - CLKBUF2 : CLKINT
196   - PORT MAP(
197   - -- Inputs
198   - A => mux2_out,
199   - -- Outputs
200   - Y => mux2_out_buff
201   - );
202   -
203   -------------------------------------
204   --- Counters of the two TERO outputs --
205   -------------------------------------
206   -
207   - PROCESS(mux1_out_buff, rst)
208   - BEGIN
209   - IF (rst = '0') THEN
210   - cnt1 <= (OTHERS => '0'); -- reset of counters
211   - ELSIF rising_edge(mux1_out_buff) THEN
212   - IF ctrl = '0' OR cnt1_done_int = '1' OR cnt2_done_int = '1' THEN
213   - cnt1 <= cnt1;
214   - ELSE
215   - cnt1 <= cnt1 + 1;
216   - END IF;
217   - END IF;
218   - END PROCESS;
219   ---
220   - PROCESS(mux2_out_buff, rst) -- counting process for the second counter
221   - BEGIN
222   - IF (rst = '0') THEN
223   - cnt2 <= (OTHERS => '0'); -- reset of counters
224   - ELSIF rising_edge(mux2_out_buff) THEN
225   - IF ctrl = '0' OR cnt1_done_int = '1' OR cnt2_done_int = '1' THEN
226   - cnt2 <= cnt2;
227   - ELSE
228   - cnt2 <= cnt2 + 1;
229   - END IF;
230   - END IF;
231   - END PROCESS;
232   -
233   ----------------------------------------
234   --- Indication of the end of counting --
235   ----------------------------------------
236   -
237   - cnt1_done_int <= '1' WHEN ((cnt1(9) = '1') AND (cnt2_done_int = '0')) ELSE '0'; -- if the first counter reaches the final value, this signal is set to one
238   - cnt2_done_int <= '1' WHEN ((cnt2(9) = '1') AND (cnt1_done_int = '0')) ELSE '0'; -- if the second counter reaches the final value, this signal is set to one
239   -
240   - ------------------------------------------------------
241   - -- generate ctrl signal for tero cells
242   - ------------------------------------------------------
243   --- 7-bits counter
244   - PROCESS(clk)
245   - BEGIN
246   - IF rising_edge(clk) THEN
247   - IF ena = '0' THEN
248   - cnt_ctrl <= (OTHERS => '0');
249   - ctrl <= '0';
250   - strobe <= '0';
251   - ELSE
252   - IF cnt_ctrl = "00001000" THEN
253   - ctrl <= '0';
254   - strobe <= '1';
255   - cnt_ctrl <= cnt_ctrl;
256   - ELSE
257   - ctrl <= '1';
258   - strobe <= '0';
259   - cnt_ctrl <= cnt_ctrl + 1;
260   - END IF;
261   - END IF;
262   - END IF;
263   - END PROCESS;
264   -
265   - ---------------------------------------------------------------------------
266   - -- subtract the two counter value and send the MSB to the shift register
267   - ---------------------------------------------------------------------------
268   - sub_result <= cnt1 - cnt2;
269   - output_puf <= sub_result(9)&sub_result(5);
270   -
271   -END rtl;
basic_infrastructure/hdl/TERO_core.vhd View file @ 1aaf7d0
1   ----------------------------------------------------------------------
2   ---
3   --- Design unit: RO core
4   ---
5   --- File name: RO_core.vhd
6   ---
7   --- Description: RO core
8   ---
9   --- Autor: Ugo Mureddu, Hubert Curien Laboratory, France
10   ---
11   --- Copyright: Hubert Curien Laboratory
12   ---
13   --- Revision: Version 1.00, June 2016
14   ---
15   ----------------------------------------------------------------------
16   -
17   -LIBRARY ieee;
18   -USE ieee.std_logic_1164.all;
19   -USE ieee.numeric_std.all;
20   -
21   -library smartfusion2;
22   -use smartfusion2.all;
23   -
24   -ENTITY TERO_core IS
25   - GENERIC (
26   - length : INTEGER := 4
27   - );
28   - PORT(
29   - ctrl : IN STD_LOGIC := '1'; -- Enables oscillator output
30   - tero_out : OUT STD_LOGIC -- Oscillator output
31   - );
32   -END TERO_core;
33   -
34   --------------------------------------------------------------------------------
35   -ARCHITECTURE rtl OF TERO_core IS
36   --------------------------------------------------------------------------------
37   -
38   -COMPONENT buff_wrp IS
39   - PORT (
40   - i : IN STD_LOGIC;
41   - o : OUT STD_LOGIC
42   - );
43   -END COMPONENT buff_wrp;
44   -
45   --- NAND2
46   -COMPONENT NAND2 IS
47   - -- Port list
48   - PORT(
49   - -- Inputs
50   - A : IN STD_LOGIC;
51   - B : IN STD_LOGIC;
52   - -- Outputs
53   - Y : OUT STD_LOGIC
54   - );
55   -END COMPONENT;
56   -
57   -COMPONENT DFN1C0 IS
58   - PORT (
59   - D : IN STD_LOGIC;
60   - CLK : IN STD_LOGIC;
61   - CLR : IN STD_LOGIC;
62   - Q : OUT STD_LOGIC
63   - );
64   -END COMPONENT;
65   -
66   -COMPONENT INV IS
67   - PORT (
68   - A : IN STD_LOGIC;
69   - Y : OUT STD_LOGIC
70   - );
71   -END COMPONENT;
72   -
73   -ATTRIBUTE keep : BOOLEAN;
74   -
75   -SIGNAL del1, del2 : STD_LOGIC_VECTOR(length-1 DOWNTO 0):=('1', OTHERS => '0');
76   -SIGNAL dff_out : STD_LOGIC := '0';
77   -SIGNAL tff_out : STD_LOGIC := '0';
78   -
79   -ATTRIBUTE keep OF del1 : SIGNAL IS TRUE;
80   -ATTRIBUTE keep OF del2 : SIGNAL IS TRUE;
81   -
82   --- for debug only
83   -SIGNAL del : STD_LOGIC_VECTOR(8 DOWNTO 0) := ('1', OTHERS => '0');
84   -SIGNAL cnt : UNSIGNED (7 DOWNTO 0) := (OTHERS => '0');
85   -SIGNAL clk : STD_LOGIC := '0';
86   -SIGNAL ena : STD_LOGIC := '0';
87   -
88   -
89   --------------------------------------------------------------------------------
90   -BEGIN
91   -
92   ---ASSERT (length >= 2)
93   - --REPORT "RO must contain at least 2 elements. Current length="&integer'image(length)
94   - --SEVERITY ERROR;
95   --------------------------------------------------------------------------------
96   -
97   --- BUFFERS
98   -gen_buff1 : FOR ii IN 0 TO length-2 GENERATE
99   - buff_1 : buff_wrp
100   - PORT MAP
101   - (
102   - i => del1(ii),
103   - o => del1(ii+1)
104   - );
105   -END GENERATE gen_buff1;
106   -
107   -gen_buff2 : FOR ii IN 0 TO length-2 GENERATE
108   - buff_2 : buff_wrp
109   - PORT MAP
110   - (
111   - i => del2(ii),
112   - o => del2(ii+1)
113   - );
114   -END GENERATE gen_buff2;
115   -
116   -nand_1 : NAND2
117   - PORT MAP(
118   - A => del1(length-1),
119   - B => ctrl,
120   - Y => del2(0)
121   - );
122   ---
123   -nand_2 : NAND2
124   - PORT MAP(
125   - A => del2(length-1),
126   - B => ctrl,
127   - Y => del1(0)
128   - );
129   -
130   - tero_out <= del2(0);
131   -
132   --- --------------------
133   --- FOR DEBUG ONLY
134   --- --------------------
135   --- the number of oscillation is the "length" generic parameter
136   -
137   ---ro : FOR ii IN 0 TO 7 GENERATE
138   - --buff_1 : buff_wrp
139   - --PORT MAP
140   - --(
141   - --i => del(ii),
142   - --o => del(ii+1)
143   - --);
144   ---END GENERATE ro;
145   ---
146   ---del(0) <= NOT(del(8));
147   ---clk <= del(8);
148   ---
149   - --PROCESS(clk, ctrl)
150   - --BEGIN
151   - --IF ( ctrl = '0' ) THEN
152   - --cnt <= (OTHERS => '0');
153   - --ena <= '0';
154   - --ELSIF rising_edge(clk) THEN
155   - --IF cnt < length THEN
156   - --cnt <= cnt + 1;
157   - --ena <= '1';
158   - --ELSE
159   - --cnt <= cnt;
160   - --ena <= '0';
161   - --END IF;
162   - --END IF;
163   - --END PROCESS;
164   ---
165   ---tero_out <= clk AND ena;
166   -
167   -END ARCHITECTURE rtl;
basic_infrastructure/hdl/controller.vhd View file @ 1aaf7d0
1   -LIBRARY ieee;
2   -USE ieee.std_logic_1164.ALL;
3   -USE ieee.numeric_std.ALL;
4   -
5   -ENTITY controller IS
6   -
7   - PORT (
8   - clk : IN STD_LOGIC;
9   - rst_n : IN STD_LOGIC;
10   - data_received_ssi : IN STD_LOGIC_VECTOR(63 DOWNTO 0);
11   - data_received_ready : IN STD_LOGIC;
12   - ssi_ready_to_transmit : IN STD_LOGIC;
13   - PUF_data_ready : IN STD_LOGIC;
14   - rst_PUF : OUT STD_LOGIC;
15   - ena_PUF : OUT STD_LOGIC;
16   - TERO_index : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
17   - ena_response_shift_register : OUT STD_LOGIC;
18   - select_data_ssi : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
19   - send_data_SSI : OUT STD_LOGIC;
20   - selected_PUF_bit_for_parity : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
21   - ena_parity_computation : OUT STD_LOGIC;
22   - rst_n_sync_parity_module : OUT STD_LOGIC;
23   - ena_parity_shift_register : OUT STD_LOGIC;
24   - rst_parity_register : OUT STD_LOGIC
25   - );
26   -
27   -END ENTITY controller;
28   -
29   -ARCHITECTURE behavioural OF controller IS
30   -
31   - TYPE state_type IS (IDLE,
32   - WAIT_FOR_NEW_COMMAND,
33   -
34   - SELECT_LSB_RESPONSE,
35   - SEND_LSB_RESPONSE,
36   - WAIT_LSB_RESPONSE_SENT,
37   -
38   - SELECT_MSB_RESPONSE,
39   - SEND_MSB_RESPONSE,
40   - WAIT_MSB_RESPONSE_SENT,
41   -
42   - GEN_RESPONSE_BIT_PUF,
43   - STORE_RESPONSE_BIT_PUF,
44   - RESET_PUF_COUNTERS,
45   -
46   - CASCADE_MODE,
47   - WAIT_FOR_NEW_INDEXES,
48   - STORE_NEW_INDEXES,
49   - SELECT_PARITY_BIT,
50   - ENABLE_PARITY,
51   - COMPUTE_PARITY,
52   - STORE_PARITY_BIT,
53   - RESET_PARITY_MODULE,
54   -
55   - SELECT_PARITY_REGISTER,
56   - SEND_PARITY_REGISTER,
57   - WAIT_PARITY_REGISTER_SENT,
58   - RESET_PARITY_REGISTER
59   - );
60   - SIGNAL state : state_type;
61   -
62   - SIGNAL data_received_ssi_reg : STD_LOGIC_VECTOR(63 DOWNTO 0);
63   - SIGNAL data_received_ready_reg : STD_LOGIC;
64   - SIGNAL counter : UNSIGNED(6 DOWNTO 0);
65   - SIGNAL PUF_data_ready_reg : STD_LOGIC;
66   - SIGNAL block_size : UNSIGNED(6 DOWNTO 0);
67   - SIGNAL nb_blocks : UNSIGNED(7 DOWNTO 0);
68   - SIGNAL indexes : STD_LOGIC_VECTOR(63 DOWNTO 0);
69   - SIGNAL select_PUF_bit_index : UNSIGNED(6 DOWNTO 0);
70   - SIGNAL nb_indexes_processed : UNSIGNED(6 DOWNTO 0);
71   -
72   -BEGIN
73   -
74   - -- purpose: Synchronise the inputs
75   - PROCESS (clk, rst_n) IS
76   - BEGIN -- PROCESS
77   - IF rst_n = '0' THEN -- asynchronous reset (active low)
78   - data_received_ssi_reg <= (OTHERS => '0');
79   - data_received_ready_reg <= '0';
80   - PUF_data_ready_reg <= '0';
81   - ELSIF rising_edge(clk) THEN -- rising clock edge
82   - data_received_ssi_reg <= data_received_ssi;
83   - data_received_ready_reg <= data_received_ready;
84   - PUF_data_ready_reg <= PUF_data_ready;
85   - END IF;
86   - END PROCESS;
87   -
88   - -- purpose: Compute the next state
89   - PROCESS (clk, rst_n) IS
90   - BEGIN -- PROCESS
91   - IF rst_n = '0' THEN -- asynchronous reset (active low)
92   - state <= IDLE;
93   - counter <= (OTHERS => '0');
94   - indexes <= (OTHERS => '0');
95   - block_size <= (OTHERS => '0');
96   - nb_blocks <= (OTHERS => '0');
97   - nb_indexes_processed <= (OTHERS => '0');
98   - ELSIF rising_edge(clk) THEN -- rising clock edge
99   - CASE state IS
100   - WHEN IDLE =>
101   - counter <= (OTHERS => '0');
102   - IF data_received_ready_reg = '1' THEN
103   - CASE data_received_ssi_reg(3 DOWNTO 0) IS
104   - WHEN x"1" => -- 1: Generate response with counter
105   - state <= GEN_RESPONSE_BIT_PUF;
106   - WHEN x"2" => -- 2: Send out 64 LSB of the response
107   - state <= SELECT_LSB_RESPONSE;
108   - WHEN x"3" => -- 3: Send out 64 MSB of the response
109   - state <= SELECT_MSB_RESPONSE;
110   - WHEN x"4" => -- 4: CASCADE mode
111   - state <= CASCADE_MODE;
112   - WHEN x"5" => -- 5: Send out parity register
113   - state <= SELECT_PARITY_REGISTER;
114   - WHEN OTHERS =>
115   - state <= IDLE;
116   - END CASE;
117   - END IF;
118   -
119   - ------------------------------------------------------
120   - -- 1: Generate response with counter as challenge
121   - ------------------------------------------------------
122   - WHEN GEN_RESPONSE_BIT_PUF =>
123   - IF PUF_data_ready_reg = '1' THEN
124   - state <= STORE_RESPONSE_BIT_PUF;
125   - END IF;
126   -
127   - WHEN STORE_RESPONSE_BIT_PUF =>
128   - counter <= counter + 1;
129   - state <= RESET_PUF_COUNTERS;
130   -
131   - WHEN RESET_PUF_COUNTERS =>
132   - IF counter = "1000000" THEN --back to zero
133   - state <= WAIT_FOR_NEW_COMMAND;
134   - ELSE
135   - state <= GEN_RESPONSE_BIT_PUF;
136   - END IF;
137   -
138   - -------------------------------------
139   - -- 2: Send out 64 LSB of the response
140   - -------------------------------------
141   - WHEN SELECT_LSB_RESPONSE =>
142   - state <= SEND_LSB_RESPONSE;
143   -
144   - WHEN SEND_LSB_RESPONSE =>
145   - state <= WAIT_LSB_RESPONSE_SENT;
146   -
147   - WHEN WAIT_LSB_RESPONSE_SENT =>
148   - IF ssi_ready_to_transmit = '1' THEN
149   - state <= WAIT_FOR_NEW_COMMAND;
150   - END IF;
151   -
152   - -------------------------------------
153   - -- 3: Send out 64 MSB of the response
154   - -------------------------------------
155   - WHEN SELECT_MSB_RESPONSE =>
156   - state <= SEND_MSB_RESPONSE;
157   -
158   - WHEN SEND_MSB_RESPONSE =>
159   - state <= WAIT_MSB_RESPONSE_SENT;
160   -
161   - WHEN WAIT_MSB_RESPONSE_SENT =>
162   - IF ssi_ready_to_transmit = '1' THEN
163   - state <= WAIT_FOR_NEW_COMMAND;
164   - END IF;
165   -
166   - ------------------
167   - -- 4: CASCADE mode
168   - ------------------
169   - WHEN CASCADE_MODE =>
170   - state <= SELECT_PARITY_BIT;
171   - indexes <= data_received_ssi_reg(63 DOWNTO 0);
172   - select_PUF_bit_index <= "0000010";
173   - nb_indexes_processed <= (OTHERS => '0');
174   - nb_blocks <= unsigned(data_received_ssi_reg(15 DOWNTO 8));
175   - CASE data_received_ssi_reg(7 DOWNTO 4) IS
176   - WHEN x"1" =>
177   - block_size <= "0000001"; -- 1
178   - WHEN x"2" =>
179   - block_size <= "0000010"; -- 2
180   - WHEN x"3" =>
181   - block_size <= "0000100"; -- 4
182   - WHEN x"4" =>
183   - block_size <= "0001000"; -- 8
184   - WHEN x"5" =>
185   - block_size <= "0010000"; -- 16
186   - WHEN x"6" =>
187   - block_size <= "0100000"; -- 32
188   - WHEN x"7" =>
189   - block_size <= "1000000"; -- 64
190   - WHEN OTHERS =>
191   - state <= WAIT_FOR_NEW_COMMAND;
192   - END CASE;
193   -
194   - WHEN SELECT_PARITY_BIT =>
195   - IF select_PUF_bit_index = 8 THEN
196   - state <= WAIT_FOR_NEW_INDEXES;
197   - ELSE
198   - state <= ENABLE_PARITY;
199   - END IF;
200   -
201   - WHEN WAIT_FOR_NEW_INDEXES =>
202   - IF data_received_ready_reg = '0' THEN
203   - state <= STORE_NEW_INDEXES;
204   - END IF;
205   -
206   - WHEN STORE_NEW_INDEXES =>
207   - IF data_received_ready_reg = '1' THEN
208   - indexes <= data_received_ssi_reg(63 DOWNTO 0);
209   - select_PUF_bit_index <= (OTHERS => '0');
210   - state <= ENABLE_PARITY;
211   - END IF;
212   -
213   - WHEN ENABLE_PARITY =>
214   - nb_indexes_processed <= nb_indexes_processed + 1;
215   - state <= COMPUTE_PARITY;
216   -
217   - WHEN COMPUTE_PARITY =>
218   - select_PUF_bit_index <= select_PUF_bit_index + 1;
219   - IF nb_indexes_processed = block_size THEN
220   - state <= STORE_PARITY_BIT;
221   - nb_blocks <= nb_blocks - 1;
222   - ELSE
223   - state <= SELECT_PARITY_BIT;
224   - END IF;
225   -
226   - WHEN STORE_PARITY_BIT =>
227   - nb_indexes_processed <= (OTHERS => '0');
228   - state <= RESET_PARITY_MODULE;
229   -
230   - WHEN RESET_PARITY_MODULE =>
231   - IF nb_blocks = 0 THEN
232   - state <= WAIT_FOR_NEW_COMMAND;
233   - ELSE
234   - state <= SELECT_PARITY_BIT;
235   - END IF;
236   -
237   - ------------------------------
238   - -- 5: Send out parity register
239   - ------------------------------
240   - WHEN SELECT_PARITY_REGISTER =>
241   - state <= SEND_PARITY_REGISTER;
242   -
243   - WHEN SEND_PARITY_REGISTER =>
244   - state <= WAIT_PARITY_REGISTER_SENT;
245   -
246   - WHEN WAIT_PARITY_REGISTER_SENT =>
247   - IF ssi_ready_to_transmit = '1' THEN
248   - state <= RESET_PARITY_REGISTER;
249   - END IF;
250   -
251   - WHEN RESET_PARITY_REGISTER =>
252   - state <= WAIT_FOR_NEW_COMMAND;
253   -
254   - ----------------------------------------------------
255   - -- Buffer state to avoid considering a command twice
256   - ----------------------------------------------------
257   - WHEN WAIT_FOR_NEW_COMMAND =>
258   - IF data_received_ready_reg = '0' THEN
259   - state <= IDLE;
260   - END IF;
261   -
262   - END CASE;
263   - END IF;
264   - END PROCESS;
265   -
266   - ---------------------
267   - -- Decode the outputs
268   - ---------------------
269   -
270   - select_data_SSI <= "00" WHEN state = SELECT_LSB_RESPONSE ELSE
271   - "00" WHEN state = SEND_LSB_RESPONSE ELSE
272   - "01" WHEN state = SELECT_MSB_RESPONSE ELSE
273   - "01" WHEN state = SEND_MSB_RESPONSE ELSE
274   - "10" WHEN state = SELECT_PARITY_REGISTER ELSE
275   - "10" WHEN state = SEND_PARITY_REGISTER ELSE
276   - "11";
277   - send_data_SSI <= '1' WHEN state = SEND_LSB_RESPONSE ELSE
278   - '1' WHEN state = SEND_MSB_RESPONSE ELSE
279   - '1' WHEN state = SEND_PARITY_REGISTER ELSE
280   - '0';
281   - rst_PUF <= '0' WHEN state = RESET_PUF_COUNTERS ELSE
282   - '0' WHEN state = IDLE ELSE
283   - '0' WHEN state = WAIT_FOR_NEW_COMMAND ELSE
284   - '1';
285   - ena_PUF <= '1' WHEN state = GEN_RESPONSE_BIT_PUF ELSE '0';
286   - ena_response_shift_register <= '1' WHEN state = STORE_RESPONSE_BIT_PUF ELSE '0';
287   - TERO_index <= STD_LOGIC_VECTOR(counter);
288   -
289   - rst_parity_register <= '0' WHEN state = RESET_PARITY_REGISTER ELSE
290   - '1';
291   - ena_parity_computation <= '1' WHEN state = ENABLE_PARITY ELSE
292   - '0';
293   - ena_parity_shift_register <= '1' WHEN state = STORE_PARITY_BIT ELSE
294   - '0';
295   - selected_PUF_bit_for_parity <= indexes(TO_INTEGER(x"0" & select_PUF_bit_index(2 DOWNTO 0))*8+6
296   - DOWNTO
297   - TO_INTEGER(x"0" & select_PUF_bit_index(2 DOWNTO 0))*8);
298   - rst_n_sync_parity_module <= '0' WHEN state = STORE_PARITY_BIT ELSE
299   - '1';
300   -END ARCHITECTURE behavioural;
basic_infrastructure/hdl/mux4x64.vhd View file @ 1aaf7d0
1   ----------------------------------------------------------------------
2   ---
3   --- Design unit: Multiplexor
4   ---
5   --- File name: mux.vhd
6   ---
7   --- Description: Connect the oscillating RO cells to the counters
8   ---
9