scope.io.tio2 = "serial_tx" scope.io.hs2 = "clkgen" scope.glitch.output = "glitch_only" scope.io.glitch_lp = False scope.io.glitch_hp = True print(scope.io.glitch_lp) print(scope.io.glitch_hp) target.go_cmd = "" target.key_cmd = "" print("Erase target...") # program the XMEGA with the built hex file # programmer = AVRProgrammer() programmer = XMEGAProgrammer() programmer.scope = scope programmer._logging = None programmer.find() programmer.erase() print("Programming...") # programmer.program("~/software/chipwhisperer/hardware/victims/firmware/glitch-simple/glitchsimple-CW304.hex", memtype="flash") programmer.program("glitchsimple.hex", memtype="flash", verify=False) programmer.close() scope.glitch.trigger_src = 'ext_single' traces = [] outputs = [] widths = []
def test_tutorial_B6(self): scope = self.scope target = self.target programmer = XMEGAProgrammer() programmer.scope = scope programmer._logging = None programmer.find() programmer.erase() aes_firmware_dir = os.path.join(FIRMWARE_DIR, 'simpleserial-aes') aes_hex = os.path.join(aes_firmware_dir, r"simpleserial-aes-CW303.hex") programmer.program(aes_hex, memtype="flash", verify=True) programmer.close() # setup scope parameters scope.gain.gain = 45 scope.adc.samples = 3000 scope.adc.offset = 1250 scope.adc.basic_mode = "rising_edge" scope.clock.clkgen_freq = 7370000 scope.clock.adc_src = "clkgen_x4" scope.trigger.triggers = "tio4" scope.io.tio1 = "serial_rx" scope.io.tio2 = "serial_tx" scope.io.hs2 = "clkgen" ktp = AcqKeyTextPattern_Basic(target=target) traces = [] textin = [] N = 100 # Number of traces print('Capturing traces...') target.init() for i in tqdm(range(N)): key, text = ktp.newPair() # manual creation of a key, text pair can be substituted here textin.append(text) target.reinit() target.setModeEncrypt() # only does something for targets that support it target.loadEncryptionKey(key) target.loadInput(text) # run aux stuff that should run before the scope arms here scope.arm() # run aux stuff that should run after the scope arms here target.go() timeout=50 # wait for target to finish while target.isDone() is False and timeout: timeout -= 1 time.sleep(0.01) try: ret = scope.capture() if ret: logging.warning('Timeout happened during acquisition') except IOError as e: logging.error('IOError: %s' % str(e)) # run aux stuff that should happen after trace here _ = target.readOutput() # for keep the v1.1 protocol working traces.append(scope.getLastTrace()) knownkey = key pt = np.asarray(textin) traces = np.asarray(traces) numtraces = np.shape(traces)[0] numpoint = np.shape(traces)[1] bestguess = [0] * 16 pge = [256] * 16 print("Attacking subkeys...") for bnum in tqdm(range(0, 16)): cpaoutput = [0] * 256 maxcpa = [0] * 256 for kguess in range(0, 256): #print("Subkey %2d, hyp = %02x: " % (bnum, kguess), end='') # Initialize arrays & variables to zero sumnum = np.zeros(numpoint) sumden1 = np.zeros(numpoint) sumden2 = np.zeros(numpoint) hyp = np.zeros(numtraces) for tnum in range(0, numtraces): hyp[tnum] = self.HW[self.intermediate(pt[tnum][bnum], kguess)] # Mean of hypothesis meanh = np.mean(hyp, dtype=np.float64) # Mean of all points in trace meant = np.mean(traces, axis=0, dtype=np.float64) # For each trace, do the following for tnum in range(0, numtraces): hdiff = (hyp[tnum] - meanh) tdiff = traces[tnum, :] - meant sumnum = sumnum + (hdiff * tdiff) sumden1 = sumden1 + hdiff * hdiff sumden2 = sumden2 + tdiff * tdiff cpaoutput[kguess] = sumnum / np.sqrt(sumden1 * sumden2) maxcpa[kguess] = max(abs(cpaoutput[kguess])) #print(maxcpa[kguess]) bestguess[bnum] = np.argmax(maxcpa) cparefs = np.argsort(maxcpa)[::-1] # Find PGE pge[bnum] = list(cparefs).index(knownkey[bnum]) print("Best Key Guess: ", end="") for b in bestguess: print("%02x " % b, end="") print("") print("PGE: ", end="") for b in pge: print("%02d " % b, end="") self.assertLess(sum(pge), 5)
def test_TutorialB5(self): self.aes_firmware_dir = os.path.join(FIRMWARE_DIR, "simpleserial-aes") # Build firmware logging.info('Building firmware from make file') call = ["make", "--directory", self.aes_firmware_dir, "PLATFORM=CW303"] logging.info(call) exit_code = subprocess.check_call(call) if exit_code == 0: logging.info('Finished building firmware') else: logging.error('Build Failed with exit code {}'.format(exit_code)) # create capture gui self.auto_ui = test_tools.FakeUI() self.auto_ui.create_capture() capture_gui = self.auto_ui.capture.gui # TODO use the created project (currently cause PyQtGraph error) # connect scope and target logging.info('Executing "connect_cwlite_simpleserial.py"') connect_cwlite_simpleserial = os.path.join( CAPTURE_SCRIPTS_DIR, "connect_cwlite_simpleserial.py") capture_gui.execute(script_path=connect_cwlite_simpleserial) self.auto_ui.updateUI() logging.info('Finished executing "connect_cwlite_simpleserial.py"') # program the target with the built firmware programmer = XMEGAProgrammer() programmer.scope = capture_gui.scope programmer._logging = None programmer.find() programmer.erase() aes_hex = os.path.join(self.aes_firmware_dir, r"simpleserial-aes-CW303.hex") programmer.program(aes_hex, memtype="flash", verify=True) programmer.close() # Execute the setup script for simple serial aes logging.info('Executing "setup_cwlite_xmega_aes.py"') setup_cwlite_xmega_aes = os.path.join(CAPTURE_SCRIPTS_DIR, "setup_cwlite_xmega_aes.py") capture_gui.execute(script_path=setup_cwlite_xmega_aes) self.auto_ui.updateUI() logging.info('Finished executing "setup_cwlite_xmega.py"') # Create a basic key text pattern logging.info('Creating key text pattern') ktp = AcqKeyTextPattern_Basic() logging.info('Finished creating key text pattern') # Capture traces logging.info('Capturing traces') capture_gui.execute(string='self.api.setNumTraces(60)') capture_gui.doCapture(capture_gui.captureM) self.auto_ui.updateUI() logging.info('Finished capturing traces') # Close the capture gui and open the analyzer gui logging.info('Closing capture and opening analyzer') self.auto_ui.close_capture() self.auto_ui.create_analyzer() analyzer_gui = self.auto_ui.analyzer.gui logging.info('Finished closing capture and opening analyzer') # TODO Open the project in the analyzer gui #logging.info('Opening project') #analyzer_gui.project = self.project #logging.info('Finished opening project') # Perform the attack attack_cpa_script = os.path.join(ANALYZER_SCRIPTS_DIR, "attack_cpa.py") logging.info('Executing attack script {}'.format(attack_cpa_script)) analyzer_gui.execute(script_path=attack_cpa_script) self.auto_ui.updateUI() logging.info('Finished executing attack script') # check if the key is the expected key result_subkeys = self.auto_ui.analyzer.gui.results_table.sub_key_row(1) result_key = u' '.join(result_subkeys) actual_key = ktp.initkey logging.info('Actual Key: {}'.format(actual_key)) logging.info('Result Key: {}'.format(result_key)) if result_key == actual_key: logging.info('Sucess, keys match') else: logging.error('Keys do not match') self.assertEqual(result_key, actual_key) # close the analayzer self.auto_ui.close_analyzer()
def test_tutorial_A2(self): # build the firmware self.glitch_simple_firmware_dir = os.path.join(FIRMWARE_DIR, "glitch-simple") # Build firmware logging.info('Building firmware from make file') call = ["make", "--directory", self.glitch_simple_firmware_dir, "PLATFORM=CW303"] logging.info(call) exit_code = subprocess.check_call(call) if exit_code == 0: logging.info('Finished building firmware') else: logging.error('Build Failed with exit code {}'.format(exit_code)) # connect the scope and target scope = self.scope target = self.target # program the XMEGA with the built hex file programmer = XMEGAProgrammer() programmer.scope = scope programmer._logging = None programmer.find() programmer.erase() glitch_simple_hex = os.path.join(self.glitch_simple_firmware_dir, r"glitchsimple-CW303.hex") programmer.program(glitch_simple_hex, memtype="flash", verify=True) programmer.close() # setup parameters needed for glitch the XMEGA scope.glitch.clk_src = 'clkgen' scope.gain.gain = 45 scope.adc.samples = 3000 scope.adc.offset = 0 scope.adc.basic_mode = "rising_edge" scope.clock.clkgen_freq = 7370000 scope.clock.adc_src = "clkgen_x4" scope.trigger.triggers = "tio4" scope.io.tio1 = "serial_rx" scope.io.tio2 = "serial_tx" scope.io.hs2 = "glitch" target.go_cmd = "" target.key_cmd = "" # set glitch parameters # trigger glitches with external trigger scope.glitch.trigger_src = 'ext_single' scope.glitch.repeat = 105 traces = [] outputs = [] # named tuples to make it easier to change the scope of the test Range = namedtuple('Range', ['min', 'max', 'step']) width_range = Range(-10, 10, 1.7) offset_range = Range(-10, 10, 1.7) # glitch cycle scope.glitch.width = width_range.min success = False target.init() while scope.glitch.width < width_range.max and not success: scope.glitch.offset = offset_range.min while scope.glitch.offset < offset_range.max and not success: # call before trace things here # flush the garbage from the computer's target read buffer target.ser.flush() # target enters reset mode scope.io.pdic = 'low' # run aux stuff that should run before the scope arms here scope.arm() # run aux stuff that should run after the scope arms here # target exits reset mode scope.io.pdic = 'high' timeout = 50 # wait for target to finish while target.isDone() is False and timeout: timeout -= 1 time.sleep(0.01) try: ret = scope.capture() if ret: logging.warning('Timeout happened during acquisition') except IOError as e: logging.error('IOError: %s' % str(e)) #textout = target.readOutput() # raises invalid literal for int base 16 # get the results trace = scope.getLastTrace() output = target.ser.read(target.output_len * 2, timeout=10) traces.append(trace) outputs.append(output) if '1234' in repr(output): success = True # run aux stuff that should happen after trace here scope.glitch.offset += offset_range.step scope.glitch.width += width_range.step self.assertTrue(success, 'There is no "1234" in the outputs, maybe glitch1() in c file is not active')