Commit 26e706e8cc1b82f332a0dc0c1205980497531215

Authored by Brice Colombier
1 parent 6ecd6a48d0
Exists in master

Problem in AW decoder

Showing 25 changed files with 2545 additions and 104 deletions

AW_decoder/AW_decoder.vhd View file @ 26e706e
... ... @@ -4,46 +4,38 @@
4 4 ENTITY AW_decoder IS
5 5  
6 6 PORT (
7   - formatted_AW : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
8   - AW : OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
  7 + formatted_AW : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
  8 + AW : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
9 9  
10 10 END ENTITY AW_decoder;
11 11  
12 12 ARCHITECTURE rtl OF AW_decoder IS
13 13  
14   - SIGNAL locking_0 IS STD_LOGIC;
15   - SIGNAL locking_1 IS STD_LOGIC;
  14 + SIGNAL locking_0 : STD_LOGIC;
  15 + SIGNAL locking_1 : STD_LOGIC;
16 16  
17 17 BEGIN
18 18  
19   - -- Formatted AW: 01010100
20   - -- AW: 11111110 10011000
  19 + -- Formatted AW: 0101
  20 + -- AW: 0000 1100
21 21  
22 22 -- Lock AND
23   - locking_1 <= formatted_AW(4) AND formatted_AW(6);
24   - AW(12) <= locking_1;
25   - AW(9) <= locking_1;
26   - AW(10) <= locking_1;
27   - AW(11) <= locking_1;
28   - AW(15) <= locking_1;
29   - AW(14) <= locking_1;
30   - AW(13) <= locking_1;
  23 + locking_1 <= formatted_AW(2);
31 24  
32 25 -- Lock OR
33   - locking_0 <= formatted_AW(7) OR formatted_AW(5);
34   - AW(8) <= locking_0;
  26 + locking_0 <= formatted_AW(3);
  27 + AW(4) <= locking_0;
  28 + AW(5) <= locking_0;
  29 + AW(6) <= locking_0;
  30 + AW(7) <= locking_0;
35 31  
36 32 -- Mask ANDs
37   - AW(7) <= formatted_AW(2)
38   - AW(3) <= formatted_AW(2)
39   - AW(4) <= formatted_AW(2)
  33 + AW(2) <= formatted_AW(0);
  34 + AW(3) <= formatted_AW(0);
40 35  
41 36 -- Mask ORs
42   - AW(5) <= formatted_AW(1);
43   - AW(2) <= formatted_AW(1);
44   - AW(1) <= formatted_AW(3);
45   - AW(0) <= formatted_AW(3);
46   - AW(6) <= formatted_AW(0);
  37 + AW(1) <= formatted_AW(1);
  38 + AW(0) <= formatted_AW(1);
47 39  
48 40 END ARCHITECTURE rtl;
AW_decoder/gen_AW_decoder.py View file @ 26e706e
... ... @@ -81,7 +81,7 @@
81 81 vhd_file.write(" AW("+str(outputs)+") <= formatted_AW("+str(inputs)+");\n")
82 82 elif type(inputs) == int and type(outputs) == list:
83 83 for output in outputs:
84   - vhd_file.write(" AW("+str(output)+") <= formatted_AW("+str(inputs)+")\n")
  84 + vhd_file.write(" AW("+str(output)+") <= formatted_AW("+str(inputs)+");\n")
85 85 elif type(inputs) == list and type(outputs) == int:
86 86 vhd_file.write(" AW("+str(outputs)+") <= "+" AND ".join(["formatted_AW("+str(i)+")" for i in inputs])+";\n")
87 87 vhd_file.write("\n -- Mask ORs\n")
88 88  
... ... @@ -118,12 +118,12 @@
118 118 # Architecture
119 119 vhd_file.write("ARCHITECTURE rtl OF AW_decoder IS\n\n")
120 120 if locking:
121   - vhd_file.write(" SIGNAL locking_0 IS STD_LOGIC;\n")
122   - vhd_file.write(" SIGNAL locking_1 IS STD_LOGIC;\n\n")
  121 + vhd_file.write(" SIGNAL locking_0 : STD_LOGIC;\n")
  122 + vhd_file.write(" SIGNAL locking_1 : STD_LOGIC;\n\n")
123 123 vhd_file.write("BEGIN\n\n")
124 124  
125 125  
126   -def gen_AW_decoder (AW, width_formatted_AW, locking=True, masking=True, formatted_AW=""):
  126 +def gen_AW_decoder (AW, width_formatted_AW, locking=True, masking=True, path = "./", formatted_AW=""):
127 127 """Generates a decoder for the Activation Word
128 128  
129 129 AW: activation word, provided MSB first
... ... @@ -135,7 +135,9 @@
135 135 if locking:
136 136 if masking:
137 137 try:
138   - unlocking_word, unmasking_word = AW.split()
  138 + unlocking_word, unmasking_word = AW.split(" ")
  139 + print unlocking_word
  140 + print unmasking_word
139 141 except ValueError:
140 142 raise ValueError("Incorrect AW provided, must be \"AW_lock AW_mask\"")
141 143 else:
... ... @@ -151,7 +153,7 @@
151 153 else:
152 154 raise ValueError("At least one of locking or masking must be set to True")
153 155  
154   - with open("AW_decoder.vhd", "w") as vhd_file:
  156 + with open(path+"AW_decoder.vhd", "w") as vhd_file:
155 157 # Header
156 158  
157 159 if (masking and not locking) or (locking and not masking):
... ... @@ -160,10 +162,6 @@
160 162 formatted_AW = ''.join([str(int(2*rd.random())) for i in xrange(width_formatted_AW)])
161 163 elif len(formatted_AW) != width_formatted_AW:
162 164 raise ValueError("Length of provided formatted AW does not match width_formatted_AW")
163   - print "Formatted AW:", formatted_AW
164   - print " AW:", AW
165   - print unlocking_word
166   - print unmasking_word
167 165 vhd_file.write(" -- Formatted AW: "+formatted_AW+"\n")
168 166 vhd_file.write(" -- AW: "+AW+"\n")
169 167  
170 168  
... ... @@ -195,15 +193,12 @@
195 193 formatted_AW_locking = ''.join([str(int(2*rd.random())) for i in xrange(width_formatted_AW/2)])
196 194 while set(formatted_AW_masking) != set(['0', '1']):
197 195 formatted_AW_masking = ''.join([str(int(2*rd.random())) for i in xrange(width_formatted_AW/2)])
  196 + formatted_AW = formatted_AW_masking + formatted_AW_locking
198 197 elif len(formatted_AW) != width_formatted_AW:
199 198 raise ValueError("Length of provided formatted AW does not match width_formatted_AW")
200 199 else:
201 200 formatted_AW_locking = formatted_AW[len(formatted_AW)/2:]
202 201 formatted_AW_masking = formatted_AW[:len(formatted_AW)/2]
203   - print "Formatted AW:", formatted_AW_locking+formatted_AW_masking
204   - print " AW:", AW
205   - print "Formatted AW locking", formatted_AW_locking
206   - print "Formatted AW masking", formatted_AW_masking
207 202 vhd_file.write(" -- Formatted AW: "+formatted_AW_locking+formatted_AW_masking+"\n")
208 203 vhd_file.write(" -- AW: "+AW+"\n")
209 204  
210 205  
... ... @@ -237,11 +232,11 @@
237 232 write_masking_part_to_file(vhd_file, assoc_mask_ANDs, assoc_mask_ORs)
238 233  
239 234 vhd_file.write("\nEND ARCHITECTURE rtl;\n")
240   -
  235 + print "Formatted AW:", formatted_AW
241 236 return formatted_AW
242 237  
243 238 if __name__ == "__main__":
244   - # gen_AW_decoder("00000011", 8, locking=False, masking=True)
245   - # gen_AW_decoder("01010101", 8, locking=True, masking=False)
246   - gen_AW_decoder("11111110 10011000", 8, locking=True, masking=True)
  239 + # print gen_AW_decoder("00000011", 8, locking=False, masking=True)
  240 + # print gen_AW_decoder("01010101", 8, locking=True, masking=False)
  241 + print gen_AW_decoder("0000 1100", 4, locking=True, masking=True)
  1 +LIBRARY ieee;
  2 +USE ieee.std_logic_1164.ALL;
  3 +
  4 +ENTITY OTP IS
  5 +
  6 + GENERIC (
  7 + WIDTH : INTEGER := 128);
  8 +
  9 + PORT (
  10 + key : IN STD_LOGIC_VECTOR(WIDTH - 1 DOWNTO 0);
  11 + input : IN STD_LOGIC_VECTOR(WIDTH - 1 DOWNTO 0);
  12 + output : OUT STD_LOGIC_VECTOR(WIDTH - 1 DOWNTO 0));
  13 +
  14 +END ENTITY OTP;
  15 +
  16 +ARCHITECTURE rtl OF OTP IS
  17 +
  18 +BEGIN -- ARCHITECTURE rtl
  19 +
  20 + FOR i IN 0 TO WIDTH - 1 GENERATE
  21 + output(i) <= key(i) XOR input(i);
  22 + END GENERATE;
  23 +
  24 +END ARCHITECTURE rtl;
add_frame_elements.py View file @ 26e706e
... ... @@ -115,7 +115,8 @@
115 115 text="Format:")
116 116 self.format_label.grid(row=1, column=0, sticky=E)
117 117 self.filename_entry=Entry(self.file_frame,
118   - textvariable=self.filename, width=100)
  118 + textvariable=self.filename,
  119 + width=100)
119 120 self.filename_entry.grid(row=0, column=1, columnspan=2, sticky="EW")
120 121 self.button_open_design=Button(self.file_frame,
121 122 text="Search...",
122 123  
123 124  
124 125  
... ... @@ -219,36 +220,31 @@
219 220 command=self.modify_design)
220 221 self.modify_design_button.grid(row=4, column=0)
221 222 # -------------------------------------------------------
222   - self.generate_modified_design_simple_frame = LabelFrame(self.generate_save_modified_design_frame,
223   - text = "Simple")
224   - self.generate_modified_design_simple_frame.pack(side="left",
225   - expand=1,
226   - fill="both")
227   - self.generate_modified_design_wrapped_frame = LabelFrame(self.generate_save_modified_design_frame,
228   - text = "Wrapped")
229   - self.generate_modified_design_wrapped_frame.pack(side="left",
230   - expand=1,
231   - fill="both")
232   - self.generated_design_format_label = Label(self.generate_modified_design_simple_frame,
  223 + # self.generate_modified_design_simple_frame = LabelFrame(self.generate_save_modified_design_frame,
  224 + # text = "Simple")
  225 + # self.generate_modified_design_simple_frame.pack(side="left",
  226 + # expand=1,
  227 + # fill="both")
  228 + self.generated_design_format_label = Label(self.generate_save_modified_design_frame,
233 229 text="Output format:")
234 230 self.generated_design_format_label.grid(row=0,
235 231 column=0,
236 232 sticky=E)
237   - self.generated_design_format_bench = Radiobutton(self.generate_modified_design_simple_frame,
238   - text="BENCH (.txt)",
239   - variable=self.generated_design_format,
240   - value="bench")
241   - self.generated_design_format_bench.grid(row=0,
242   - column=1,
243   - sticky=W)
244   - self.generated_design_format_vhd = Radiobutton(self.generate_modified_design_simple_frame,
  233 + self.generated_design_format_vhd = Radiobutton(self.generate_save_modified_design_frame,
245 234 text="VHDL (.vhd)",
246 235 variable=self.generated_design_format,
247 236 value="vhd")
248   - self.generated_design_format_vhd.grid(row=1,
  237 + self.generated_design_format_vhd.grid(row=0,
249 238 column=1,
250 239 sticky=W)
251   - self.generate_modified_design_button=Button(self.generate_modified_design_simple_frame,
  240 + self.generated_design_format_bench = Radiobutton(self.generate_save_modified_design_frame,
  241 + text="BENCH (.txt)",
  242 + variable=self.generated_design_format,
  243 + value="bench")
  244 + self.generated_design_format_bench.grid(row=1,
  245 + column=1,
  246 + sticky=W)
  247 + self.generate_modified_design_button=Button(self.generate_save_modified_design_frame,
252 248 text="Generate and save modified design",
253 249 state="normal",
254 250 command= self.generate_save_modified_design,
255 251  
256 252  
257 253  
258 254  
259 255  
260 256  
261 257  
262 258  
263 259  
264 260  
265 261  
266 262  
267 263  
268 264  
269 265  
270 266  
271 267  
272 268  
273 269  
274 270  
275 271  
276 272  
277 273  
... ... @@ -256,76 +252,109 @@
256 252 self.generate_modified_design_button.grid(row=2,
257 253 column=0,
258 254 sticky=W)
259   - self.modified_design_saved_label = Label(self.generate_modified_design_simple_frame,
  255 + self.modified_design_saved_label = Label(self.generate_save_modified_design_frame,
260 256 textvariable=self.message_modified_design_saved)
261 257 self.modified_design_saved_label.grid(row=2,
262 258 column=1,
263 259 sticky=W)
264   - self.save_associated_activation_word_simple_button=Button(self.generate_modified_design_simple_frame,
  260 + self.save_associated_activation_word_simple_button=Button(self.generate_save_modified_design_frame,
265 261 text="Save associated Activation word",
266 262 state="normal",
267   - command=self.save_AW,
  263 + command=self.save_associated_AW,
268 264 width=32)
269 265 self.save_associated_activation_word_simple_button.grid(row=3,
270 266 column=0,
271 267 sticky=W)
272   - self.activation_word_saved_label = Label(self.generate_modified_design_simple_frame,
  268 + self.activation_word_saved_label = Label(self.generate_save_modified_design_frame,
273 269 textvariable=self.message_AW_saved)
274 270 self.activation_word_saved_label.grid(row=3,
275 271 column=1,
276 272 sticky=W)
277   - self.crypto_label = Label(self.generate_modified_design_wrapped_frame,
  273 + self.modified_design_to_wrap_label=Label(self.wrap_modified_design_frame,
  274 + text="Design to wrap:")
  275 + self.modified_design_to_wrap_label.grid(row=0, column=0, sticky=E)
  276 + self.modified_design_to_wrap_entry=Entry(self.wrap_modified_design_frame,
  277 + width=150,
  278 + textvariable=self.modified_design_to_wrap)
  279 + self.modified_design_to_wrap_entry.grid(row=0,
  280 + column=1,
  281 + sticky="EW")
  282 + self.button_open_modified_design_to_wrap=Button(self.wrap_modified_design_frame,
  283 + text="Search...",
  284 + command=self.select_modified_design_to_wrap)
  285 + self.button_open_modified_design_to_wrap.grid(row=0, column=2)
  286 + self.associated_activation_word_label = Label(self.wrap_modified_design_frame,
  287 + text="Associated Activation word:")
  288 + self.associated_activation_word_label.grid(sticky=E)
  289 + self.associated_activation_word_display_label = Label(self.wrap_modified_design_frame,
  290 + textvariable=self.associated_activation_word,
  291 + font=("Courier", 8),
  292 + background="white",
  293 + width=20)
  294 + self.associated_activation_word_display_label.grid(row=1, column=1, sticky="EW", padx=10)
  295 +
  296 + self.open_associated_activation_word_wrapped_button=Button(self.wrap_modified_design_frame,
  297 + text="Search...",
  298 + state="normal",
  299 + command=self.open_associated_activation_word)
  300 + self.open_associated_activation_word_wrapped_button.grid(row=1,
  301 + column=2,
  302 + sticky=W)
  303 +
  304 + self.crypto_label = Label(self.wrap_modified_design_frame,
278 305 text="Crypto:")
279   - self.crypto_label.grid(row=0,
  306 + self.crypto_label.grid(row=2,
280 307 column=0,
281 308 sticky = E)
282   - self.select_crypto_OTP = Radiobutton(self.generate_modified_design_wrapped_frame,
  309 + self.select_crypto_OTP = Radiobutton(self.wrap_modified_design_frame,
283 310 text="One Time Pad",
284 311 variable=self.crypto,
285 312 value="OTP")
286   - self.select_crypto_OTP.grid(row=0,
  313 + self.select_crypto_OTP.grid(row=2,
287 314 column=1,
288 315 sticky=W)
289   - self.select_crypto_PRESENT = Radiobutton(self.generate_modified_design_wrapped_frame,
  316 + self.select_crypto_PRESENT = Radiobutton(self.wrap_modified_design_frame,
290 317 text="PRESENT",
  318 + state=DISABLED,
291 319 variable=self.crypto,
292 320 value="PRESENT")
293   - self.select_crypto_PRESENT.grid(row=1,
  321 + self.select_crypto_PRESENT.grid(row=3,
294 322 column=1,
295 323 sticky=W)
296   - self.key_derivation_label = Label(self.generate_modified_design_wrapped_frame,
  324 + self.key_derivation_label = Label(self.wrap_modified_design_frame,
297 325 text="Key generation:")
298   - self.key_derivation_label.grid(row=2,
  326 + self.key_derivation_label.grid(row=4,
299 327 column=0,
300 328 sticky = E)
301   - self.select_key_derivation_none = Radiobutton(self.generate_modified_design_wrapped_frame,
  329 + self.select_key_derivation_none = Radiobutton(self.wrap_modified_design_frame,
302 330 text="None",
303 331 variable=self.key_derivation,
304 332 value="None")
305   - self.select_key_derivation_none.grid(row=2,
  333 + self.select_key_derivation_none.grid(row=4,
306 334 column=1,
307 335 sticky=W)
308   - self.select_key_derivation_blake2 = Radiobutton(self.generate_modified_design_wrapped_frame,
  336 + self.select_key_derivation_blake2 = Radiobutton(self.wrap_modified_design_frame,
309 337 text="Blake2 hashing",
  338 + state=DISABLED,
310 339 variable=self.key_derivation,
311 340 value="Blake2")
312   - self.select_key_derivation_blake2.grid(row=3,
  341 + self.select_key_derivation_blake2.grid(row=5,
313 342 column=1,
314 343 sticky=W)
315   - self.generate_wrapped_design_button=Button(self.generate_modified_design_wrapped_frame,
  344 + self.generate_wrapped_design_button=Button(self.wrap_modified_design_frame,
316 345 text="Generate and save wrapped design",
317 346 state="normal",
318   - #command= self.generate_save_wrapped_design,
  347 + command= self.generate_save_wrapped_design,
319 348 width=32)
320   - self.generate_wrapped_design_button.grid(row=4,
  349 + self.generate_wrapped_design_button.grid(row=6,
321 350 column=0,
322 351 sticky=W)
323   - self.save_associated_activation_word_wrapped_button=Button(self.generate_modified_design_wrapped_frame,
324   - text="Save associated Activation word",
  352 + self.save_associated_activation_word_wrapped_button=Button(self.wrap_modified_design_frame,
  353 + text="Save formatted Activation word",
325 354 state="normal",
326   - command=self.save_AW,
  355 + command=self.save_formatted_AW,
327 356 width=32)
328   - self.save_associated_activation_word_wrapped_button.grid(row=5,
  357 + self.save_associated_activation_word_wrapped_button.grid(row=7,
329 358 column=0,
330 359 sticky=W)
331 360  
... ... @@ -49,6 +49,8 @@
49 49 from response_converter.response_converter import response_converter_to_hex
50 50 from response_converter.response_converter import response_converter_to_bin_list
51 51  
  52 +from AW_decoder.gen_AW_decoder import gen_AW_decoder
  53 +
52 54 class App:
53 55  
54 56 """Main class for the demonstrator GUI app"""
... ... @@ -57,8 +59,8 @@
57 59  
58 60 self.master = master
59 61  
60   - self.master.maxsize(width=800, height=460)
61   - self.master.minsize(width=800, height=460)
  62 + # self.master.maxsize(width=800, height=560)
  63 + # self.master.minsize(width=800, height=560)
62 64 self.master.resizable(width=False, height=False)
63 65 self.master.title("SALWARE IP protection tool")
64 66 self.master.iconbitmap(default='./contents/icon.ico')
... ... @@ -68,7 +70,7 @@
68 70  
69 71 # Tabs
70 72 build_tabs(self)
71   -
  73 +
72 74 # Menu bar
73 75 build_menu(self)
74 76  
75 77  
76 78  
... ... @@ -84,9 +86,10 @@
84 86 # Status bar
85 87 status_bar(self)
86 88  
87   -
88 89 def select_file(self):
  90 + self.update_status("")
89 91  
  92 +
90 93 ftypes = [("All netlist files", ".txt; .blif; .slif; .edf; .vhd; .v"),
91 94 ("BENCH files", ".txt"),
92 95 ("BLIF files", ".blif"),
93 96  
... ... @@ -100,7 +103,15 @@
100 103 self.filename.set(tkFileDialog.askopenfilename(initialdir = "./user_space/",
101 104 filetypes=ftypes))
102 105  
  106 + def select_modified_design_to_wrap(self):
  107 + self.update_status("")
  108 +
  109 + ftypes = [("VHDL files", ".vhd")]
  110 + self.modified_design_to_wrap.set(tkFileDialog.askopenfilename(initialdir = "./user_space/",
  111 + filetypes=ftypes))
  112 +
103 113 def build_graph(self):
  114 + self.update_status("")
104 115 self.update_status("Building the graph from file "+self.filename.get().split("/")[-1]+"...")
105 116 self.master.config(cursor="wait")
106 117 self.graph_info_label.configure(foreground="black")
107 118  
108 119  
... ... @@ -127,14 +138,15 @@
127 138 self.graph_info.set(str(str(len(self.nodes))+" nodes, "+
128 139 str(len(self.prim_in))+" inputs, "+
129 140 str(len(self.prim_out))+" outputs."))
130   - self.update_status("")
  141 + self.update_status("Graph built")
131 142 except:
132 143 self.update_status("Error in building the graph")
133   -
  144 +
134 145 self.master.config(cursor="")
135 146 self.master.update()
136 147  
137 148 def open_server_reference_response(self):
  149 + self.update_status("")
138 150 rrtypes = [("Reference response file", ".txt")]
139 151 self.server_reference_response_file.set(tkFileDialog.askopenfilename(initialdir = "./../User_space/",
140 152 filetypes=rrtypes))
... ... @@ -149,6 +161,7 @@
149 161 self.update_status("")
150 162  
151 163 def open_activation_word(self):
  164 + self.update_status("")
152 165 awtypes = [("Activation word", ".txt")]
153 166 self.activation_word_file = tkFileDialog.askopenfilename(initialdir = "./../User_space/",
154 167 filetypes=awtypes)
155 168  
... ... @@ -159,7 +172,21 @@
159 172 self.update_status("The file could not be parsed as an Activation Word file")
160 173 else:
161 174 self.activation_word.set(line)
  175 + print self.activation_word.get()
162 176  
  177 + def open_associated_activation_word(self):
  178 + self.update_status("")
  179 + awtypes = [("Activation word file", ".txt")]
  180 + self.associated_activation_word_file = tkFileDialog.askopenfilename(initialdir = "./../User_space/",
  181 + filetypes=awtypes)
  182 + with open(self.associated_activation_word_file, "r") as awfile:
  183 + line = awfile.readline() # First line of the file
  184 + line = awfile.readline() # Get the second line
  185 + if not set(line) <= {"0", "1", " ", "\n"}:
  186 + self.update_status("The file could not be parsed as an Activation Word file")
  187 + else:
  188 + self.associated_activation_word.set(line)
  189 +
163 190 def round_masking(self, _): # Dummy second argument
164 191 self.masking_overhead.set(int(round(self.masking_overhead.get())))
165 192  
... ... @@ -167,6 +194,7 @@
167 194 self.locking_overhead.set(int(round(self.locking_overhead.get())))
168 195  
169 196 def get_PUF_response(self):
  197 + self.update_status("")
170 198 self.PUF_response_displayed.set("")
171 199 try:
172 200 self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
173 201  
... ... @@ -179,11 +207,13 @@
179 207 self.update_status("Response could not be obtained")
180 208  
181 209 def save_as_reference_response(self):
  210 + self.update_status("")
182 211 with open("./user_space/rr.txt", "w") as rrfile:
183 212 rrfile.write("Reference response: "+self.PUF_response_displayed.get())
184 213 self.update_status("Reference response saved under ./user_space/rr.txt")
185 214  
186 215 def pop_up_about(self):
  216 + self.update_status("")
187 217 self.top = Toplevel(background="White")
188 218 self.top.title("About")
189 219  
... ... @@ -210,6 +240,7 @@
210 240 self.label_logo_RA.pack()
211 241  
212 242 def pop_up_license(self):
  243 + self.update_status("")
213 244 self.top = Toplevel()
214 245 self.top.title("License")
215 246 try:
... ... @@ -224,6 +255,7 @@
224 255 self.msg.pack()
225 256  
226 257 def connect(self):
  258 + self.update_status("")
227 259 self.tcl_obj.eval(self.board_manager.source_tcl_package())
228 260 tcl_return = self.tcl_obj.eval(self.board_manager.connect(self.com_port.get()))
229 261 if tcl_return == "-1": # Error handling
... ... @@ -237,6 +269,7 @@
237 269 self.status.set("")
238 270  
239 271 def disconnect(self):
  272 + self.update_status("")
240 273 try:
241 274 self.tcl_obj.eval(self.board_manager.disconnect())
242 275 self.com_port_button_disconnect.configure(state=DISABLED)
243 276  
... ... @@ -248,8 +281,16 @@
248 281 pass
249 282  
250 283 def modify_design(self):
  284 + self.update_status("")
251 285 self.unlocking_word = ""
252 286 self.unmasking_word = ""
  287 + self.update_status("Modifying the design...")
  288 + self.master.config(cursor="wait")
  289 + self.graph_info_label.configure(foreground="black")
  290 + self.master.update()
  291 + self.locking_inputs = []
  292 + self.masking_inputs = []
  293 +
253 294 if self.locking.get():
254 295 self.graph_modified, self.unlocking_word, self.locking_inputs = locking(self.g,
255 296 self.prim_in,
256 297  
257 298  
... ... @@ -270,10 +311,15 @@
270 311 self.nodes,
271 312 self.masking_overhead.get(),
272 313 self.masking_heuristic.get())
273   - print self.unlocking_word, self.unmasking_word
274   - print self.locking_inputs, self.masking_inputs
  314 + self.update_status("Modifications done")
  315 + self.master.config(cursor="")
  316 + self.master.update()
275 317  
  318 + print self.locking_inputs
  319 + print self.masking_inputs
  320 +
276 321 def derive_key_from_response(self):
  322 + self.update_status("")
277 323 self.salt = bytes(''.join(random.SystemRandom().choice(["0", "1"]) for _ in range(32)))
278 324 PRK_f = BLAKE2s(digest_size=32, key=self.salt)
279 325 PRK_f.update(self.PUF_response_displayed)
... ... @@ -285,6 +331,7 @@
285 331 self.update_status("Key saved under "+key_file_name)
286 332  
287 333 def generate_save_modified_design(self):
  334 + self.update_status("")
288 335 filename = self.filename.get().split("/")[-1]
289 336 filename = filename.split(".")
290 337 filename[0]+="_mod"
291 338  
292 339  
293 340  
294 341  
... ... @@ -300,18 +347,64 @@
300 347 convert_back_bench(self.graph_modified, filename)
301 348 self.update_status(str("Modified design saved under "+filename))
302 349  
303   - def save_AW(self):
  350 + def save_associated_AW(self):
  351 + self.update_status("")
304 352 filename = self.filename.get().split("/")[-1]
305 353 filename = filename.split(".")
306   - filename[0]+="_mod_AW"
  354 + filename[0]+="_mod_associated_AW"
307 355 filename[1] = "txt"
308 356 filename = ".".join(filename)
309 357 filename = "/".join(self.filename.get().split("/")[:-1])+"/"+filename
310 358 with open(filename, "w") as aw_file:
311 359 aw_file.write("Unlocking word concatenated with unmasking word\n"+self.unlocking_word+" "+self.unmasking_word)
312   - self.update_status(str("Activation word saved under "+filename))
  360 + self.update_status(str("Associated activation word saved under "+filename))
313 361  
  362 + def save_formatted_AW(self):
  363 + self.update_status("")
  364 + filename = self.modified_design_to_wrap.get().split("/")[-1]
  365 + filename = filename.split(".")
  366 + filename[0]+="_formatted_AW"
  367 + filename[1] = "txt"
  368 + filename = ".".join(filename)
  369 + filename = "/".join(self.modified_design_to_wrap.get().split("/")[:-1])+"/"+filename
  370 + print filename
  371 + with open(filename, "w") as aw_file:
  372 + aw_file.write("Formatted Activation Word\n"+self.formatted_AW)
  373 + self.update_status(str("Formatted activation word saved under "+filename))
  374 +
  375 + def generate_save_wrapped_design(self):
  376 + # Inputs:
  377 + # -> modified_design_to_wrap
  378 + # -> associated_activation_word
  379 + self.update_status("")
  380 + self.master.config(cursor="wait")
  381 + self.graph_info_label.configure(foreground="black")
  382 + self.master.update()
  383 + if self.associated_activation_word.get()[-1] == " ":
  384 + locking = True
  385 + masking = False
  386 + elif self.associated_activation_word.get()[0] == " ":
  387 + masking = True
  388 + locking = False
  389 + elif len(self.associated_activation_word.get().split(" ")) == 2:
  390 + masking = True
  391 + locking = True
  392 + print locking
  393 + print masking
  394 + try:
  395 + self.formatted_AW = gen_AW_decoder(self.associated_activation_word.get(),
  396 + 128, #128-bit responses
  397 + locking = locking,
  398 + masking = masking,
  399 + path = "./user_space/")
  400 + self.update_status("AW decoder generated")
  401 + except:
  402 + self.update_status("An error occured while generating the AW decoder")
  403 + self.master.config(cursor="")
  404 + self.master.update()
  405 +
314 406 def perform_reconciliation(self):
  407 + self.update_status("")
315 408 self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
316 409 self.tcl_obj.eval(self.board_manager.generate_response())
317 410 server_before = self.server_reference_response
318 411  
319 412  
... ... @@ -335,13 +428,15 @@
335 428 self.status.set(text)
336 429  
337 430 def reset_board(self, port=2):
  431 + self.update_status("")
338 432 self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
339 433  
340 434 def reset(self):
  435 + self.update_status("")
341 436 print ("To be implemented soon")
342 437  
343 438 if __name__ == "__main__":
344   -
  439 +
345 440 fenetre = Tk()
346 441 app = App(fenetre)
347 442  
basic_infrastructure/hdl/TEROPUF_core.vhd View file @ 26e706e
  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 @ 26e706e
  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 + );