1+ from test .penetrationtests .sca .host_scripts .sca_otbn_functions import *
2+ from communication .sca_otbn_commands import OTOTBN
3+ from python .runfiles import Runfiles
4+ from communication .chip import *
5+ from test .penetrationtests .util .utils import *
6+ import os
7+ import json
8+ import random
9+
10+ ignored_keys_set = set ([])
11+
12+ def reset_test (opentitantool , target ):
13+ reset_target (opentitantool )
14+ while True :
15+ read_line = str (target .readline ().decode ().strip ())
16+ if len (read_line ) > 0 :
17+ if "firmware_sca.c" in read_line :
18+ return True
19+ else :
20+ return False
21+
22+
23+ def init_test (opentitantool , target ):
24+ otbnsca = OTOTBN (target , "ujson" )
25+ device_id , owner_page , boot_log , boot_measurements , version = otbnsca .init ()
26+ device_id_json = json .loads (device_id )
27+ owner_page_json = json .loads (owner_page )
28+ boot_log_json = json .loads (boot_log )
29+ boot_measurements_json = json .loads (boot_measurements )
30+
31+ expected_device_id_keys = {
32+ "device_id" ,
33+ "rom_digest" ,
34+ "icache_en" ,
35+ "dummy_instr_en" ,
36+ "clock_jitter_locked" ,
37+ "clock_jitter_en" ,
38+ "sram_main_readback_locked" ,
39+ "sram_main_readback_en" ,
40+ "sram_ret_readback_locked" ,
41+ "sram_ret_readback_en"
42+ }
43+ actual_device_id_keys = set (device_id_json .keys ())
44+
45+ if not actual_device_id_keys == expected_device_id_keys :
46+ print ("device_id keys do not match the expected set." )
47+ print (f"Expected: { expected_device_id_keys } " )
48+ print (f"Actual: { actual_device_id_keys } " )
49+ return False
50+
51+ expected_owner_page_keys = {
52+ "config_version" ,
53+ "sram_exec_mode" ,
54+ "ownership_key_alg" ,
55+ "update_mode" ,
56+ "min_security_version_bl0" ,
57+ "lock_constraint"
58+ }
59+ actual_owner_page_keys = set (owner_page_json .keys ())
60+ if not expected_owner_page_keys == actual_owner_page_keys :
61+ print ("owner_page keys do not match the expected set." )
62+ print (f"Expected: { expected_owner_page_keys } " )
63+ print (f"Actual: { actual_owner_page_keys } " )
64+ return False
65+
66+ expected_boot_log_keys = {
67+ "digest" ,
68+ "identifier" ,
69+ "scm_revision_low" ,
70+ "scm_revision_high" ,
71+ "rom_ext_slot" ,
72+ "rom_ext_major" ,
73+ "rom_ext_minor" ,
74+ "rom_ext_size" ,
75+ "bl0_slot" ,
76+ "ownership_state" ,
77+ "ownership_transfers" ,
78+ "rom_ext_min_sec_ver" ,
79+ "bl0_min_sec_ver" ,
80+ "primary_bl0_slot" ,
81+ "retention_ram_initialized"
82+ }
83+ actual_boot_log_keys = set (boot_log_json .keys ())
84+ if not expected_boot_log_keys == actual_boot_log_keys :
85+ print ("boot_log keys do not match the expected set." )
86+ print (f"Expected: { expected_boot_log_keys } " )
87+ print (f"Actual: { actual_boot_log_keys } " )
88+ return False
89+
90+ expected_boot_measurements_keys = {
91+ "bl0" ,
92+ "rom_ext"
93+ }
94+ actual_boot_measurements_keys = set (boot_measurements_json .keys ())
95+ if not expected_boot_measurements_keys == actual_boot_measurements_keys :
96+ print ("boot_measurements keys do not match the expected set." )
97+ print (f"Expected: { expected_boot_measurements_keys } " )
98+ print (f"Actual: { actual_boot_measurements_keys } " )
99+ return False
100+
101+ if "PENTEST" not in version :
102+ print ("Did not receive a PENTEST version." )
103+ print (f"Actual: { version } " )
104+ return False
105+
106+ return True
107+
108+ def char_combi_operations_batch_test (opentitantool_path , iterations , num_segments ):
109+ trigger = 0
110+ fixed_data1 = 0
111+ fixed_data2 = 0
112+ print_flag = True
113+ actual_result = char_combi_operations_batch (opentitantool_path , iterations , num_segments , fixed_data1 , fixed_data2 , print_flag , trigger )
114+ try :
115+ actual_result_json = json .loads (actual_result )
116+ except :
117+ print ("char_combi_operations_batch gave an unexpected result" )
118+ print (f"Input fixed_data1 { fixed_data1 } and fixed_data2 { fixed_data2 } " )
119+ print (f"Actual: { actual_result } " )
120+ return False
121+
122+ # Calculate the expected result
123+ fixed_data_array1 = [fixed_data1 for _ in range (8 )]
124+ fixed_data_array2 = [fixed_data2 for _ in range (8 )]
125+ add = int_to_array ((array_to_int (fixed_data_array1 )+ array_to_int (fixed_data_array2 ))% (1 << 256 ))
126+ sub = int_to_array ((array_to_int (fixed_data_array1 )- array_to_int (fixed_data_array2 ))% (1 << 256 ))
127+ xor = int_to_array ((array_to_int (fixed_data_array1 )^ array_to_int (fixed_data_array2 ))% (1 << 256 ))
128+ shift = int_to_array ((array_to_int (fixed_data_array1 )<< 1 )% (1 << 256 ))
129+ fixed_data_array1 = [fixed_data1 , fixed_data1 , 0 , 0 , 0 , 0 , 0 , 0 ]
130+ fixed_data_array2 = [fixed_data2 , fixed_data2 , 0 , 0 , 0 , 0 , 0 , 0 ]
131+ mult = int_to_array ((array_to_int (fixed_data_array1 )* array_to_int (fixed_data_array2 ))% (1 << 256 ))
132+ FG = 0
133+ if fixed_data1 == fixed_data2 :
134+ FG += 8
135+ if fixed_data1 < fixed_data2 :
136+ FG += 1
137+ if sub [0 ] & 0x1 :
138+ FG += 4
139+ if (array_to_int (sub ) >> 255 ) & 0x1 :
140+ FG += 2
141+
142+ expected_result_json = {
143+ "result1" : [fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 ],
144+ "result2" : [fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 ],
145+ "result3" : add ,
146+ "result4" : sub ,
147+ "result5" : xor ,
148+ "result6" : shift ,
149+ "result7" : mult ,
150+ "result8" : FG ,
151+ }
152+ if not compare_json_data (actual_result_json , expected_result_json , ignored_keys_set ):
153+ print ("char_combi_operations_batch_fvsr failed" )
154+ print (f"Input fixed_data1 { fixed_data1 } and fixed_data2 { fixed_data2 } " )
155+ print (f"Expected: { expected_result_json } " )
156+ print (f"Actual: { actual_result_json } " )
157+ print ("" )
158+ return False
159+
160+ fixed_data1 = 1
161+ fixed_data2 = 1
162+ print_flag = True
163+ actual_result = char_combi_operations_batch (opentitantool_path , iterations , num_segments , fixed_data1 , fixed_data2 , print_flag , trigger )
164+ try :
165+ actual_result_json = json .loads (actual_result )
166+ except :
167+ print ("char_combi_operations_batch gave an unexpected result" )
168+ print (f"Input fixed_data1 { fixed_data1 } and fixed_data2 { fixed_data2 } " )
169+ print (f"Actual: { actual_result } " )
170+ return False
171+
172+ # Calculate the expected result
173+ fixed_data_array1 = [fixed_data1 for _ in range (8 )]
174+ fixed_data_array2 = [fixed_data2 for _ in range (8 )]
175+ add = int_to_array ((array_to_int (fixed_data_array1 )+ array_to_int (fixed_data_array2 ))% (1 << 256 ))
176+ sub = int_to_array ((array_to_int (fixed_data_array1 )- array_to_int (fixed_data_array2 ))% (1 << 256 ))
177+ xor = int_to_array ((array_to_int (fixed_data_array1 )^ array_to_int (fixed_data_array2 ))% (1 << 256 ))
178+ shift = int_to_array ((array_to_int (fixed_data_array1 )<< 1 )% (1 << 256 ))
179+ fixed_data_array1 = [fixed_data1 , fixed_data1 , 0 , 0 , 0 , 0 , 0 , 0 ]
180+ fixed_data_array2 = [fixed_data2 , fixed_data2 , 0 , 0 , 0 , 0 , 0 , 0 ]
181+ mult = int_to_array ((array_to_int (fixed_data_array1 )* array_to_int (fixed_data_array2 ))% (1 << 256 ))
182+ FG = 0
183+ if fixed_data1 == fixed_data2 :
184+ FG += 8
185+ if fixed_data1 < fixed_data2 :
186+ FG += 1
187+ if sub [0 ] & 0x1 :
188+ FG += 4
189+ if (array_to_int (sub ) >> 255 ) & 0x1 :
190+ FG += 2
191+
192+ expected_result_json = {
193+ "result1" : [fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 ],
194+ "result2" : [fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 ],
195+ "result3" : add ,
196+ "result4" : sub ,
197+ "result5" : xor ,
198+ "result6" : shift ,
199+ "result7" : mult ,
200+ "result8" : FG ,
201+ }
202+ if not compare_json_data (actual_result_json , expected_result_json , ignored_keys_set ):
203+ print ("char_combi_operations_batch_fvsr failed" )
204+ print (f"Input fixed_data1 { fixed_data1 } and fixed_data2 { fixed_data2 } " )
205+ print (f"Expected: { expected_result_json } " )
206+ print (f"Actual: { actual_result_json } " )
207+ print ("" )
208+ return False
209+
210+ fixed_data1 = random .getrandbits (32 )
211+ fixed_data2 = random .getrandbits (32 )
212+ print_flag = True
213+ actual_result = char_combi_operations_batch (opentitantool_path , iterations , num_segments , fixed_data1 , fixed_data2 , print_flag , trigger )
214+ try :
215+ actual_result_json = json .loads (actual_result )
216+ except :
217+ print ("char_combi_operations_batch gave an unexpected result" )
218+ print (f"Input fixed_data1 { fixed_data1 } and fixed_data2 { fixed_data2 } " )
219+ print (f"Actual: { actual_result } " )
220+ return False
221+
222+ # Calculate the expected result
223+ fixed_data_array1 = [fixed_data1 for _ in range (8 )]
224+ fixed_data_array2 = [fixed_data2 for _ in range (8 )]
225+ add = int_to_array ((array_to_int (fixed_data_array1 )+ array_to_int (fixed_data_array2 ))% (1 << 256 ))
226+ sub = int_to_array ((array_to_int (fixed_data_array1 )- array_to_int (fixed_data_array2 ))% (1 << 256 ))
227+ xor = int_to_array ((array_to_int (fixed_data_array1 )^ array_to_int (fixed_data_array2 ))% (1 << 256 ))
228+ shift = int_to_array ((array_to_int (fixed_data_array1 )<< 1 )% (1 << 256 ))
229+ fixed_data_array1 = [fixed_data1 , fixed_data1 , 0 , 0 , 0 , 0 , 0 , 0 ]
230+ fixed_data_array2 = [fixed_data2 , fixed_data2 , 0 , 0 , 0 , 0 , 0 , 0 ]
231+ mult = int_to_array ((array_to_int (fixed_data_array1 )* array_to_int (fixed_data_array2 ))% (1 << 256 ))
232+ FG = 0
233+ if fixed_data1 == fixed_data2 :
234+ FG += 8
235+ if fixed_data1 < fixed_data2 :
236+ FG += 1
237+ if sub [0 ] & 0x1 :
238+ FG += 4
239+ if (array_to_int (sub ) >> 255 ) & 0x1 :
240+ FG += 2
241+
242+ expected_result_json = {
243+ "result1" : [fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 ],
244+ "result2" : [fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 , fixed_data1 ],
245+ "result3" : add ,
246+ "result4" : sub ,
247+ "result5" : xor ,
248+ "result6" : shift ,
249+ "result7" : mult ,
250+ "result8" : FG ,
251+ }
252+ if not compare_json_data (actual_result_json , expected_result_json , ignored_keys_set ):
253+ print ("char_combi_operations_batch_fvsr failed" )
254+ print (f"Input fixed_data1 { fixed_data1 } and fixed_data2 { fixed_data2 } " )
255+ print (f"Expected: { expected_result_json } " )
256+ print (f"Actual: { actual_result_json } " )
257+ print ("" )
258+ return False
259+
260+ return True
261+
262+ def main ():
263+ r = Runfiles .Create ()
264+ opentitantool_path = r .Rlocation ("lowrisc_opentitan/sw/host/opentitantool/opentitantool" )
265+
266+ firmware_target_name = os .environ .get ("SELECTED_FIRMWARE_TARGET" , "pen_test_sca_silicon_owner_gb_rom_ext" )
267+ firmware_path = r .Rlocation (f"lowrisc_opentitan/sw/device/tests/penetrationtests/firmware/{ firmware_target_name } .img" )
268+
269+ target = DUT ()
270+
271+ flash_target (opentitantool_path , firmware_path )
272+ target .dump_all ()
273+
274+ if not reset_test (opentitantool_path , target ):
275+ print ("Reset test failure" )
276+ return False
277+
278+ if not init_test (opentitantool_path , target ):
279+ print ("Init test failure" )
280+ return False
281+
282+ iterations = 10
283+ num_segments_list = [1 , 2 , 5 , 10 , 12 ]
284+
285+ for num_segments in num_segments_list :
286+ char_combi_operations_batch_test (opentitantool_path , iterations , num_segments )
287+
288+ print ("Testing finished" )
289+ return True
290+
291+ if __name__ == "__main__" :
292+ main ()
0 commit comments