def flash(self, fw_path: str) -> bool: try: cw.program_target(self.scope, self.programmer, fw_path) except Exception as e: print(e) return False return True
def programmer( self, dot_hex_path: str, programmer_type: str, reconnect: bool = True, ) -> None: self._check_connection(raise_exception=True) if programmer_type is None or programmer_type.lower() not in ( 'xmega', 'stm32f'): raise RuntimeError( f"'{dot_hex_path}' is unsupported programmer type. (Available: xmega, stm32f)" ) if not os.path.exists(dot_hex_path): raise RuntimeError("The .hex file does not exist.") if programmer_type.lower() == "xmega": programmer = cw.programmers.XMEGAProgrammer else: programmer = cw.programmers.STM32FProgrammer cw.program_target(self._scope, programmer, dot_hex_path) if reconnect: self.reconnect() pass
def doIt(binary): print(f"flashing binary {binary}") cw.program_target(scope, prog, binary) # wait for all the output from the board print(f"output starts ({binary}):") while True: response = target.read(timeout=0) if response != None and response != "": print(response, end='', flush=True) if "#" in response: break print(f"{binary} done.")
def initialize(): # ChipWhisperer Lite setup scope = cw.scope() scope.default_setup() # Program the target board target = cw.target(scope) prog = cw.programmers.XMEGAProgrammer cw.program_target(scope, prog, fw_path) # Prepare scope for capturing scope.gain.db = 34 # works best with this gain for some reason scope.adc.samples = 1700 - 170 scope.adc.offset = 500 + 700 + 170 # Return the scope and target handles return scope, target
def setup_device(name): """Convience function for setting up and programing a CW/Target pair Args: name (str): String representing the target configuration. Currently supports 'STM32F3', 'CW305', 'XMEGA', 'STM32F3-mbed', 'K82F', 'STM32F4' returns: Setup scope and target objects """ scope = cw.scope() if name == "CW305": scope.gain.db = 25 scope.adc.samples = 129 scope.adc.offset = 0 scope.adc.basic_mode = "rising_edge" scope.clock.clkgen_freq = 7370000 scope.clock.adc_src = "extclk_x4" scope.trigger.triggers = "tio4" scope.io.tio1 = "serial_rx" scope.io.tio2 = "serial_tx" scope.io.hs2 = "disabled" target = cw.target(scope, cw.targets.CW305, bsfile="cw305_top.bit", force=False) target.vccint_set(1.0) # we only need PLL1: target.pll.pll_enable_set(True) target.pll.pll_outenable_set(False, 0) target.pll.pll_outenable_set(True, 1) target.pll.pll_outenable_set(False, 2) # run at 10 MHz: target.pll.pll_outfreq_set(10E6, 1) # 1ms is plenty of idling time target.clkusbautooff = True target.clksleeptime = 1 else: target = cw.target(scope) scope.default_setup() scope.adc.samples = 24400 if name == "XMEGA": cw.program_target(scope, cw.programmers.XMEGAProgrammer, "AES-xmega.hex") elif name == "STM32F3": cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES.hex") elif name == "STM32F3-mbed": cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-mbed.hex") elif name == "K82F": scope.adc.samples=3500 elif name == "STM32F4": cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-f4.hex") scope.adc.samples=5000 return scope,target
def setup_device(name): scope = cw.scope() if name == "CW305": scope.gain.db = 25 scope.adc.samples = 129 scope.adc.offset = 0 scope.adc.basic_mode = "rising_edge" scope.clock.clkgen_freq = 7370000 scope.clock.adc_src = "extclk_x4" scope.trigger.triggers = "tio4" scope.io.tio1 = "serial_rx" scope.io.tio2 = "serial_tx" scope.io.hs2 = "disabled" target = cw.target(scope, cw.targets.CW305, bsfile="cw305_top.bit", force=False) target.vccint_set(1.0) # we only need PLL1: target.pll.pll_enable_set(True) target.pll.pll_outenable_set(False, 0) target.pll.pll_outenable_set(True, 1) target.pll.pll_outenable_set(False, 2) # run at 10 MHz: target.pll.pll_outfreq_set(10E6, 1) # 1ms is plenty of idling time target.clkusbautooff = True target.clksleeptime = 1 else: target = cw.target(scope) scope.default_setup() scope.adc.samples = 24400 if name == "XMEGA": cw.program_target(scope, cw.programmers.XMEGAProgrammer, "AES-xmega.hex") elif name == "STM32F3": cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES.hex") elif name == "STM32F3-mbed": cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-mbed.hex") elif name == "K82F": scope.adc.samples=3500 elif name == "STM32F4": cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-f4.hex") scope.adc.samples=5000 return scope,target
import os from chipwhisperer.capture.api.programmers import STM32FProgrammer # Initiate a new STM32F Program # STM32 being the ARM microcontroller that we are using # https://en.wikipedia.org/wiki/STM32#STM32_F3 program = STM32FProgrammer # Get the path to the current folder # Adjust accordingly aes_firmware_dir = os.path.dirname(os.path.realpath(__file__)) aes_hex_path = os.path.join(aes_firmware_dir, r"simpleserial-target-CWLITEARM.hex") # Apply the program to the actual target # This allows us to run the hex code on the microcontroller cw.program_target(scope, program, aes_hex_path) ######################################## # Capture a trace of our binary ######################################## # Define some dummy data data = bytearray([0x42] * 16) # Arm the capture board scope.arm() # Flush the UART buffer target.flush() # Send a new command to trigger our code. # Here we use scmd = 128
def main(argv): if (len(argv) != 3): print( "\nplease specify the path, type and numer of trials\npython CSIDH_glitch.py [path] [type] [ntrials]\ne.g. python CSIDH_glitch.py /home/me/chipwhisperer/hardware/victims/firmware/csidh_trace/ ATTACK1 100" ) sys.exit() else: random.seed(13) PATH = argv[0] TYPE = argv[1] # ATTACK1 or ATTACK2 NTRIAL = int(argv[2]) FULLPATH = PATH + BIN # Setup_Generic ################################################################## scope = cw.scope() target = cw.target(scope) if "STM" in PLATFORM or PLATFORM == "CWLITEARM" or PLATFORM == "CWNANO": prog = cw.programmers.STM32FProgrammer elif PLATFORM == "CW303" or PLATFORM == "CWLITEXMEGA": prog = cw.programmers.XMEGAProgrammer else: prog = None import time time.sleep(0.05) scope.default_setup() def reset_target(scope): if PLATFORM == "CW303" or PLATFORM == "CWLITEXMEGA": scope.io.pdic = 'low' time.sleep(0.05) scope.io.pdic = 'high_z' # XMEGA doesn't like pdic driven high time.sleep(0.05) else: scope.io.nrst = 'low' time.sleep(0.05) scope.io.nrst = 'high' time.sleep(0.05) # Setup_Generic ################################################################## # create firmware os.chdir(PATH) #os.system('make clean PLATFORM=CWLITEARM CRYPTO_TARGET=NONE') #os.system("make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=TEST OPT=0") if ((TYPE == "ATTACK1") or (TYPE == "ATTACK1_D")): if (TYPE == "ATTACK1"): os.system( "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK1 OPT=3" ) else: os.system( "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK1_D OPT=3" ) #os.system("make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK1_D OPT=3 TYPE=CM") # Sets up sane capture defaults for this scope # 45dB gain # 5000 capture samples # 0 sample offset # rising edge trigger # 7.37MHz clock output on hs2 # 4*7.37MHz ADC clock # tio1 = serial rx # tio2 = serial tx scope.default_setup() scope.clock.adc_src = 'clkgen_x1' fw_path = FULLPATH.format(PLATFORM) print(fw_path) reset_target(scope) target.flush() cw.program_target(scope, prog, fw_path) glitches = [] glitches.append([ "[scope.glitch.width", "scope.glitch.offset", "scope.glitch.repeat", "scope.glitch.ext_offset", "good/bad/crash]" ]) if (GLITCH): setGlitch(scope) # The response took 1086919328 cycles # -O3 ext_offset = 222534093 wrong = 0 crashes = 0 for i in range(0, NTRIAL): if (GLITCH): # scope.glitch.width = random.randint(-49, 49) # scope.glitch.offset = random.randint(-49, 49) # The width of a single glitch pulse, as a percentage of one period. # One pulse can range from -49.8% to roughly 49.8% of a period. # The system may not be reliable at 0%. Note that negative widths are allowed; # these act as if they are positive widths on the other half of the clock cycle. # scope.glitch.width = random.randint(-49, 49) scope.glitch.width = -9 # The offset from a rising clock edge to a glitch pulse rising edge, # as a percentage of one period. # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge, # allowing glitches to be swept over the entire clock cycle. # scope.glitch.offset = random.randint(-49, 49) scope.glitch.offset = -38.3 # How long the glitch module waits between a trigger and a glitch. # After the glitch module is triggered, it waits for a number of clock cycles # before generating glitch pulses. This delay allows the glitch to be inserted # at a precise moment during the target’s execution to glitch specific instructions. scope.glitch.ext_offset = random.randint(0, ext_offset) # scope.glitch.ext_offset = 108466842 # The number of glitch pulses to generate per trigger. # When the glitch module is triggered, it produces a number of pulses # that can be combined with the clock signal. This setting allows for # the glitch module to produce stronger glitches (especially during voltage glitching). # Repeat counter must be in the range [1, 255]. # scope.glitch.repeat = random.randint(1, 4) scope.glitch.repeat = 3 reset_target(scope) target.flush() print("\n--------------------------------\nstarting capture " + str(i) + " : " + datetime.datetime.now().strftime("%H:%M:%S")) #scope.adc.timeout = 210 scope.arm() #scope.adc.timeout = 210 target.write("s") time.sleep(0.1) ret = scope.capture() if ret: print('Timeout happened during acquisition') time.sleep(40) if SCOPETYPE == "OPENADC": response_time = scope.adc.trig_count print("The response took {} cycles".format(response_time)) response = target.read(timeout=0) print("<output>\n" + response + "\n</output>") if (GLITCH): if "good" not in response: # Something abnormal happened if len(response) > 0: # Possible glitch! print( "\nBad shared secret\nGlitch at offset {} and repeat = {}" .format(scope.glitch.ext_offset, scope.glitch.repeat)) wrong = wrong + 1 glitches.append([ scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "bad" ]) else: # Crash, reset and try again print("\nProbably crashed at {} and repeat = {}". format(scope.glitch.ext_offset, scope.glitch.repeat)) crashes = crashes + 1 glitches.append([ scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "crash" ]) else: print( "\nGood shared secret\nGlitch at offset {} and repeat = {}" .format(scope.glitch.ext_offset, scope.glitch.repeat)) glitches.append([ scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "good" ]) print("end of capture " + str(i) + " : " + datetime.datetime.now().strftime("%H:%M:%S") + "\n--------------------------------") glitches.append(["-----------------------------"]) glitches.append(["ntrial, wrong, crashes"]) glitches.append([NTRIAL, wrong, crashes]) if (TYPE == "ATTACK1"): PATH = "attack1_" + datetime.datetime.now().strftime( "%d%m%Y_%H%M") + ".csv" else: PATH = "attack1_D_" + datetime.datetime.now().strftime( "%d%m%Y_%H%M") + ".csv" # save raw data as csv with open(PATH, mode='w') as csv_file: csv_writer = csv.writer(csv_file) for entry in glitches: csv_writer.writerow(entry) elif (TYPE == "ATTACK2"): os.system( "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK2 OPT=3" ) # Sets up sane capture defaults for this scope # 45dB gain # 5000 capture samples # 0 sample offset # rising edge trigger # 7.37MHz clock output on hs2 # 4*7.37MHz ADC clock # tio1 = serial rx # tio2 = serial tx scope.default_setup() scope.clock.adc_src = 'clkgen_x1' fw_path = FULLPATH.format(PLATFORM) print(fw_path) reset_target(scope) target.flush() cw.program_target(scope, prog, fw_path) glitches = [] glitches.append([ "[isogeny", "scope.glitch.width", "scope.glitch.offset", "scope.glitch.repeat", "scope.glitch.ext_offset", "good/bad/crash]" ]) # The response took 4846257 cycles : 1. isogeny computation # -O0 # ext_offset = 4846257 # -O3 ext_offset = 83289 wrong = 0 crashes = 0 setDefault(scope) for i in range(0, NTRIAL): if (GLITCH): #isogeny = random.randint(1, 2) isogeny = 2 if (isogeny == 1): setGlitch(scope) # The width of a single glitch pulse, as a percentage of one period. # One pulse can range from -49.8% to roughly 49.8% of a period. # The system may not be reliable at 0%. Note that negative widths are allowed; # these act as if they are positive widths on the other half of the clock cycle. # scope.glitch.width = random.randint(-49, 49) # The offset from a rising clock edge to a glitch pulse rising edge, # as a percentage of one period. # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge, # allowing glitches to be swept over the entire clock cycle. # scope.glitch.offset = random.randint(-49, 49) # How long the glitch module waits between a trigger and a glitch. # After the glitch module is triggered, it waits for a number of clock cycles # before generating glitch pulses. This delay allows the glitch to be inserted # at a precise moment during the target’s execution to glitch specific instructions. scope.glitch.ext_offset = random.randint(0, ext_offset) # scope.glitch.ext_offset = 108466842 # The number of glitch pulses to generate per trigger. # When the glitch module is triggered, it produces a number of pulses # that can be combined with the clock signal. This setting allows for # the glitch module to produce stronger glitches (especially during voltage glitching). # Repeat counter must be in the range [1, 255]. scope.glitch.repeat = random.randint(1, 4) #scope.glitch.repeat = 1 reset_target(scope) target.flush() print( "\n--------------------------------\nstarting capture " + str(i) + "\n--------------------------------\ncapture of 1. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S")) scope.adc.timeout = 180 scope.arm() scope.adc.timeout = 180 target.write("s") time.sleep(0.1) ret = scope.capture() if ret: print('Timeout happened during acquisition') #time.sleep(60) if SCOPETYPE == "OPENADC": response_time = scope.adc.trig_count print("The response took {} cycles".format(response_time)) response = target.read(timeout=0) print("<output>\n" + response + "\n</output>") print("end of 1. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S") + "\n--------------------------------") setDefault(scope) # The response took 3436390 cycles : 2. isogeny computation # -O0 # ext_offset = 3436390 # -O3 ext_offset = 8580178 if (GLITCH): if (isogeny == 2): setGlitch(scope) # The width of a single glitch pulse, as a percentage of one period. # One pulse can range from -49.8% to roughly 49.8% of a period. # The system may not be reliable at 0%. Note that negative widths are allowed; # these act as if they are positive widths on the other half of the clock cycle. # scope.glitch.width = random.randint(-49, 49) # The offset from a rising clock edge to a glitch pulse rising edge, # as a percentage of one period. # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge, # allowing glitches to be swept over the entire clock cycle. # scope.glitch.offset = random.randint(-49, 49) # How long the glitch module waits between a trigger and a glitch. # After the glitch module is triggered, it waits for a number of clock cycles # before generating glitch pulses. This delay allows the glitch to be inserted # at a precise moment during the target’s execution to glitch specific instructions. scope.glitch.ext_offset = random.randint(1, ext_offset) # scope.glitch.ext_offset = 108466842 # The number of glitch pulses to generate per trigger. # When the glitch module is triggered, it produces a number of pulses # that can be combined with the clock signal. This setting allows for # the glitch module to produce stronger glitches (especially during voltage glitching). # Repeat counter must be in the range [1, 255]. scope.glitch.repeat = random.randint(1, 4) #scope.glitch.repeat = 1 print( "\n--------------------------------\ncapture of 2. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S")) scope.adc.timeout = 60 scope.arm() scope.adc.timeout = 60 target.write("n") time.sleep(0.1) ret = scope.capture() if ret: print('Timeout happened during acquisition') #time.sleep(10) if SCOPETYPE == "OPENADC": response_time = scope.adc.trig_count print("The response took {} cycles".format(response_time)) response = target.read(timeout=0) print("<output>\n" + response + "\n</output>") print("end of 2. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S") + "\n--------------------------------") setDefault(scope) print( "\n--------------------------------\nstarting capture of result : " + datetime.datetime.now().strftime("%H:%M:%S")) scope.adc.timeout = 30 scope.arm() scope.adc.timeout = 30 target.write("n") time.sleep(0.1) ret = scope.capture() if ret: print('Timeout happened during acquisition') #time.sleep(10) if SCOPETYPE == "OPENADC": response_time = scope.adc.trig_count print("The response took {} cycles".format(response_time)) response = target.read(timeout=0) print("<output>\n" + response + "\n</output>") print("end of capture " + str(i) + " : " + datetime.datetime.now().strftime("%H:%M:%S") + "\n--------------------------------") if (GLITCH): if "good" not in response: # Something abnormal happened if len(response) > 0: # Possible glitch! print( "\nBad shared secret\nGlitching isogeny {} at offset {} and repeat = {}" .format(isogeny, scope.glitch.ext_offset, scope.glitch.repeat)) wrong = wrong + 1 glitches.append([ isogeny, scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "bad" ]) else: # Crash, reset and try again print( "\nProbably crashed at isogeny {} at {} and repeat = {}" .format(isogeny, scope.glitch.ext_offset, scope.glitch.repeat)) crashes = crashes + 1 glitches.append([ isogeny, scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "crash" ]) else: print( "\nGood shared secret\nGlitching isogeny {} at offset {} and repeat = {}" .format(isogeny, scope.glitch.ext_offset, scope.glitch.repeat)) glitches.append([ isogeny, scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "good" ]) glitches.append(["-----------------------------"]) glitches.append(["ntrial, wrong, crashes"]) glitches.append([NTRIAL, wrong, crashes]) PATH = "attack2_" + datetime.datetime.now().strftime( "%d%m%Y_%H%M") + ".csv" # save raw data as csv with open(PATH, mode='w') as csv_file: csv_writer = csv.writer(csv_file) for entry in glitches: csv_writer.writerow(entry) elif (TYPE == "ATTACK2_D"): #os.system("make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK2_D OPT=2 TYPE=CM") os.system( "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK2_D OPT=3" ) # Sets up sane capture defaults for this scope # 45dB gain # 5000 capture samples # 0 sample offset # rising edge trigger # 7.37MHz clock output on hs2 # 4*7.37MHz ADC clock # tio1 = serial rx # tio2 = serial tx scope.default_setup() scope.clock.adc_src = 'clkgen_x1' fw_path = FULLPATH.format(PLATFORM) print(fw_path) reset_target(scope) target.flush() cw.program_target(scope, prog, fw_path) glitches = [] glitches.append([ "[isogeny", "scope.glitch.width", "scope.glitch.offset", "scope.glitch.repeat", "scope.glitch.ext_offset", "good/bad/crash]" ]) # The response took 4846257 cycles : 1. isogeny computation # -O0 # ext_offset = 4846257 # -O3 ext_offset = 90082 wrong = 0 crashes = 0 setDefault(scope) test = 5639046 - 10 width = -49 for i in range(0, NTRIAL): test = test + 1 width = width + 3 reset_target(scope) target.flush() # The response took 4846257 cycles : 1. isogeny computation # -O0 # ext_offset = 4846257 # -O3 ext_offset = 90082 if (GLITCH): #isogeny = random.randint(1, 2) isogeny = 1 if (isogeny == 1): setGlitch(scope) # The width of a single glitch pulse, as a percentage of one period. # One pulse can range from -49.firmware/csidh/attack2_D_14052020_2028_m1_1.csv8% to roughly 49.8% of a period. # The system may not be reliable at 0%. Note that negative widths are allowed; # these act as if they are positive widths on the other half of the clock cycle. # scope.glitch.width = random.randint(-49, 49) scope.glitch.width = -9 # The offset from a rising clock edge to a glitch pulse rising edge, # as a percentage of one period. # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge, # allowing glitches to be swept over the entire clock cycle. # scope.glitch.offset = random.randint(-49, 49) scope.glitch.offset = -38.3 # How long the glitch module waits between a trigger and a glitch. # After the glitch module is triggered, it waits for a number of clock cycles # before generating glitch pulses. This delay allows the glitch to be inserted # at a precise moment during the target’s execution to glitch specific instructions. scope.glitch.ext_offset = random.randint(1, ext_offset) #scope.glitch.ext_offset = 57248 # The number of glitch pulses to generate per trigger. # When the glitch module is triggered, it produces a number of pulses # that can be combined with the clock signal. This setting allows for # the glitch module to produce stronger glitches (especially during voltage glitching). # Repeat counter must be in the range [1, 255]. #scope.glitch.repeat = random.randint(1, 5) scope.glitch.repeat = 3 print( "\n--------------------------------\nstarting capture " + str(i) + "\n--------------------------------\ncapture of 1. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S")) scope.adc.timeout = 10 scope.arm() scope.adc.timeout = 10 target.write("s") #time.sleep(0.1) ret = scope.capture() if ret: print('Timeout happened during acquisition') #time.sleep(5) if SCOPETYPE == "OPENADC": response_time = scope.adc.trig_count print("The response took {} cycles".format(response_time)) response = target.read(timeout=0) #print("<output>\n" + response + "\n</output>") print("end of 1. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S") + "\n--------------------------------") setDefault(scope) # The response took 3436390 cycles : 2. isogeny computation # -O0 # response_time = 3436390 # -O380392 ext_offset = 60817547 if (GLITCH): if (isogeny == 2): setGlitch(scope) # The width of a single glitch pulse, as a percentage of one period. # One pulse can range from -49.8% to roughly 49.8% of a period. # The system may not be reliable at 0%. Note that negative widths are allowed; # these act as if they are positive widths on the other half of the clock cycle. # scope.glitch.width = random.randint(-49, 49) scope.glitch.width = -9 # The offset from a rising clock edge to a glitch pulse rising edge, # as a percentage of one period. # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge, # allowing glitches to be swept over the entire clock cycle. # scope.glitch.offset = random.randint(-49, 49) scope.glitch.offset = -38.3 # How long the glitch module waits between a trigger and a glitch. # After the glitch module is triggered, it waits for a number of clock cycles # before generating glitch pulses. This delay allows the glitch to be inserted # at a precise moment during the target’s execution to glitch specific instructions. scope.glitch.ext_offset = random.randint(1, ext_offset) #scope.glitch.ext_offset = 5393209 + (i*2) #scope.glitch.ext_offset = 8050242 # The number of glitch pulses to generate per trigger. # When the glitch module is triggered, it produces a number of pulses # that can be combined with the clock signal. This setting allows for # the glitch module to produce stronger glitches (especially during voltage glitching). # Repeat counter must be in the range [1, 255]. #scope.glitch.repeat = random.randint(1, 5) scope.glitch.repeat = 3 #scope.glitch.repeat = 1 print( "\n--------------------------------\ncapture of 2. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S")) scope.adc.timeout = 10 scope.arm() scope.adc.timeout = 10 target.write("n") #time.sleep(0.1) ret = scope.capture() if ret: print('Timeout happened during acquisition') time.sleep(1) if SCOPETYPE == "OPENADC": response_time = scope.adc.trig_count print("The response took {} cycles".format(response_time)) response = target.read(timeout=0) #print("<output>\n" + response + "\n</output>") print("end of 2. isogeny : " + datetime.datetime.now().strftime("%H:%M:%S") + "\n--------------------------------") setDefault(scope) print( "\n--------------------------------\nstarting capture of result : " + datetime.datetime.now().strftime("%H:%M:%S")) scope.adc.timeout = 10 scope.arm() scope.adc.timeout = 10 target.write("n") time.sleep(0.1) ret = scope.capture() if ret: print('Timeout happened during acquisition') #time.sleep(10) if SCOPETYPE == "OPENADC": response_time = scope.adc.trig_count print("The response took {} cycles".format(response_time)) response = target.read(timeout=0) print("<output>\n" + response + "\n</output>") print("end of capture " + str(i) + " : " + datetime.datetime.now().strftime("%H:%M:%S") + "\n--------------------------------") if (GLITCH): if "good" not in response: # Something abnormal happened if len(response) > 0: # Possible glitch! print( "\nBad shared secret\nGlitching isogeny {} at offset {} and repeat = {}" .format(isogeny, scope.glitch.ext_offset, scope.glitch.repeat)) wrong = wrong + 1 glitches.append([ isogeny, scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "bad" ]) else: # Crash, reset and try again print( "\nProbably crashed at isogeny {} at {} and repeat = {}" .format(isogeny, scope.glitch.ext_offset, scope.glitch.repeat)) crashes = crashes + 1 glitches.append([ isogeny, scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "crash" ]) else: print( "\nGood shared secret\nGlitching isogeny {} at offset {} and repeat = {}" .format(isogeny, scope.glitch.ext_offset, scope.glitch.repeat)) glitches.append([ isogeny, scope.glitch.width, scope.glitch.offset, scope.glitch.repeat, scope.glitch.ext_offset, "good" ]) glitches.append(["-----------------------------"]) glitches.append(["ntrial, wrong, crashes"]) glitches.append([NTRIAL, wrong, crashes]) PATH = "attack2_D_" + datetime.datetime.now().strftime( "%d%m%Y_%H%M") + ".csv" # save raw data as csv with open(PATH, mode='w') as csv_file: csv_writer = csv.writer(csv_file) for entry in glitches: csv_writer.writerow(entry) scope.dis() target.dis()
import chipwhisperer as cw SCOPETYPE = 'OPENADC' PLATFORM = 'CWLITEXMEGA' CRYPTO_TARGET = 'AVRCRYPTOLIB' from Setup_Generic import Setup scope, prog, target = Setup(PLATFORM) fw_path = '../simpleserial-aes-CWLITEXMEGA.AVRLIB.hex' #Firmware cw.program_target(scope, prog, fw_path) import chipwhisperer.analyzer as cwa import matplotlib.pyplot as plt import progressbar from csv import writer ktp = cw.ktp.Basic() ktp.fixed_key = False leak_model = cwa.leakage_models.sbox_output num_traces = 10 def append_list_as_row(file, item): with open(file, 'a+', newline='') as write_obj: csv_writer = writer(write_obj) csv_writer.writerow(item)
import chipwhisperer as cw scope = cw.scope() target = cw.target(scope) scope.default_setup() prog = cw.programmers.STM32FProgrammer cw.program_target(scope, prog, "image-demo-CWLITEARM.hex") line = "" while True: print(target.read(), end="")